Commit 2467394e authored by Tom Lane's avatar Tom Lane

Tablespaces. Alternate database locations are dead, long live tablespaces.

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.
parent 474875f4
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers 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"> <chapter id="catalogs">
...@@ -178,6 +178,11 @@ ...@@ -178,6 +178,11 @@
<entry>planner statistics</entry> <entry>planner statistics</entry>
</row> </row>
<row>
<entry><link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link></entry>
<entry>tablespaces within this database cluster</entry>
</row>
<row> <row>
<entry><link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link></entry> <entry><link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link></entry>
<entry>triggers</entry> <entry>triggers</entry>
...@@ -1058,6 +1063,17 @@ ...@@ -1058,6 +1063,17 @@
<entry>Name of the on-disk file of this relation; 0 if none</entry> <entry>Name of the on-disk file of this relation; 0 if none</entry>
</row> </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> <row>
<entry><structfield>relpages</structfield></entry> <entry><structfield>relpages</structfield></entry>
<entry><type>int4</type></entry> <entry><type>int4</type></entry>
...@@ -1602,13 +1618,15 @@ ...@@ -1602,13 +1618,15 @@
</row> </row>
<row> <row>
<entry><structfield>datpath</structfield></entry> <entry><structfield>dattablespace</structfield></entry>
<entry><type>text</type></entry> <entry><type>oid</type></entry>
<entry></entry> <entry><literal><link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.oid</literal></entry>
<entry> <entry>
If the database is stored at an alternative location then this The default tablespace for the database.
records the location. It's either an environment variable name Within this database, all tables for which
or an absolute path, depending how it was entered. <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> </entry>
</row> </row>
...@@ -2386,6 +2404,17 @@ ...@@ -2386,6 +2404,17 @@
<entry>Owner of the namespace</entry> <entry>Owner of the namespace</entry>
</row> </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> <row>
<entry><structfield>nspacl</structfield></entry> <entry><structfield>nspacl</structfield></entry>
<entry><type>aclitem[]</type></entry> <entry><type>aclitem[]</type></entry>
...@@ -3232,6 +3261,73 @@ ...@@ -3232,6 +3261,73 @@
</sect1> </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"> <sect1 id="catalog-pg-trigger">
<title><structname>pg_trigger</structname></title> <title><structname>pg_trigger</structname></title>
......
<!-- <!--
$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"> <chapter id="managing-databases">
...@@ -298,6 +298,11 @@ ALTER DATABASE mydb SET geqo TO off; ...@@ -298,6 +298,11 @@ ALTER DATABASE mydb SET geqo TO off;
<sect1 id="manage-ag-alternate-locs"> <sect1 id="manage-ag-alternate-locs">
<title>Alternative Locations</title> <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> <para>
It is possible to create a database in a location other than the It is possible to create a database in a location other than the
default location for the installation. But remember that all database access default location for the installation. But remember that all database access
...@@ -368,21 +373,6 @@ CREATE DATABASE <replaceable>name</> WITH LOCATION '<replaceable>location</>'; ...@@ -368,21 +373,6 @@ CREATE DATABASE <replaceable>name</> WITH LOCATION '<replaceable>location</>';
Databases created in alternative locations can be Databases created in alternative locations can be
accessed and dropped like any other database. accessed and dropped like any other database.
</para> </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>
<sect1 id="manage-ag-dropdb"> <sect1 id="manage-ag-dropdb">
......
<!-- <!--
$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 PostgreSQL documentation
Complete list of usable sgml source files in this directory. Complete list of usable sgml source files in this directory.
--> -->
...@@ -44,6 +44,7 @@ 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 createSequence system "create_sequence.sgml">
<!entity createTable system "create_table.sgml"> <!entity createTable system "create_table.sgml">
<!entity createTableAs system "create_table_as.sgml"> <!entity createTableAs system "create_table_as.sgml">
<!entity createTableSpace system "create_tablespace.sgml">
<!entity createTrigger system "create_trigger.sgml"> <!entity createTrigger system "create_trigger.sgml">
<!entity createType system "create_type.sgml"> <!entity createType system "create_type.sgml">
<!entity createUser system "create_user.sgml"> <!entity createUser system "create_user.sgml">
...@@ -66,6 +67,7 @@ Complete list of usable sgml source files in this directory. ...@@ -66,6 +67,7 @@ Complete list of usable sgml source files in this directory.
<!entity dropSchema system "drop_schema.sgml"> <!entity dropSchema system "drop_schema.sgml">
<!entity dropSequence system "drop_sequence.sgml"> <!entity dropSequence system "drop_sequence.sgml">
<!entity dropTable system "drop_table.sgml"> <!entity dropTable system "drop_table.sgml">
<!entity dropTableSpace system "drop_tablespace.sgml">
<!entity dropTrigger system "drop_trigger.sgml"> <!entity dropTrigger system "drop_trigger.sgml">
<!entity dropType system "drop_type.sgml"> <!entity dropType system "drop_type.sgml">
<!entity dropUser system "drop_user.sgml"> <!entity dropUser system "drop_user.sgml">
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -22,9 +22,9 @@ PostgreSQL documentation ...@@ -22,9 +22,9 @@ PostgreSQL documentation
<synopsis> <synopsis>
CREATE DATABASE <replaceable class="PARAMETER">name</replaceable> CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
[ [ WITH ] [ OWNER [=] <replaceable class="parameter">dbowner</replaceable> ] [ [ WITH ] [ OWNER [=] <replaceable class="parameter">dbowner</replaceable> ]
[ LOCATION [=] '<replaceable class="parameter">dbpath</replaceable>' ]
[ TEMPLATE [=] <replaceable class="parameter">template</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> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -50,29 +50,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable> ...@@ -50,29 +50,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
privilege can only create databases owned by themselves. privilege can only create databases owned by themselves.
</para> </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> <para>
By default, the new database will be created by cloning the standard By default, the new database will be created by cloning the standard
system database <literal>template1</>. A different template can be system database <literal>template1</>. A different template can be
...@@ -85,12 +62,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable> ...@@ -85,12 +62,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
any installation-local objects that may have been added to any installation-local objects that may have been added to
<literal>template1</>. <literal>template1</>.
</para> </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.
</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
...@@ -115,16 +86,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable> ...@@ -115,16 +86,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">dbpath</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.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">template</replaceable></term> <term><replaceable class="parameter">template</replaceable></term>
<listitem> <listitem>
...@@ -148,6 +109,18 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable> ...@@ -148,6 +109,18 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">tablespace</replaceable></term>
<listitem>
<para>
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>
</variablelist> </variablelist>
<para> <para>
...@@ -167,9 +140,7 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable> ...@@ -167,9 +140,7 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
<para> <para>
Errors along the line of <quote>could not initialize database directory</> Errors along the line of <quote>could not initialize database directory</>
are most likely related to insufficient permissions on the data are most likely related to insufficient permissions on the data
directory, a full disk, or other file system problems. When using an directory, a full disk, or other file system problems.
alternate location, the user under
which the database server is running must have access to the location.
</para> </para>
<para> <para>
...@@ -181,13 +152,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable> ...@@ -181,13 +152,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
wrapper program around this command, provided for convenience. wrapper program around this command, provided for convenience.
</para> </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> <para>
Although it is possible to copy a database other than <literal>template1</> 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 by specifying its name as the template, this is not (yet) intended as
...@@ -205,24 +169,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable> ...@@ -205,24 +169,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
<programlisting> <programlisting>
CREATE DATABASE lusiadas; 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> </programlisting>
</para> </para>
</refsect1> </refsect1>
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -22,6 +22,7 @@ PostgreSQL documentation ...@@ -22,6 +22,7 @@ PostgreSQL documentation
<synopsis> <synopsis>
CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table</replaceable> [ USING <replaceable class="parameter">method</replaceable> ] 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> ] [, ...] ) ( { <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> ] [ WHERE <replaceable class="parameter">predicate</replaceable> ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -180,6 +181,16 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re ...@@ -180,6 +181,16 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
</listitem> </listitem>
</varlistentry> </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>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">predicate</replaceable></term> <term><replaceable class="parameter">predicate</replaceable></term>
<listitem> <listitem>
...@@ -188,6 +199,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re ...@@ -188,6 +199,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -20,8 +20,8 @@ PostgreSQL documentation ...@@ -20,8 +20,8 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
CREATE SCHEMA <replaceable class="parameter">schemaname</replaceable> [ 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> [ <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> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -80,6 +80,17 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable ...@@ -80,6 +80,17 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable
</listitem> </listitem>
</varlistentry> </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>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">schema_element</replaceable></term> <term><replaceable class="parameter">schema_element</replaceable></term>
<listitem> <listitem>
...@@ -102,8 +113,10 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable ...@@ -102,8 +113,10 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable
<para> <para>
To create a schema, the invoking user must have the To create a schema, the invoking user must have the
<literal>CREATE</> privilege for the current database. (Of course, <literal>CREATE</> privilege for the current database.
superusers bypass this check.) Also, the <literal>TABLESPACE</> option requires having
<literal>CREATE</> privilege for the specified tablespace.
(Of course, superusers bypass these checks.)
</para> </para>
</refsect1> </refsect1>
...@@ -181,6 +194,7 @@ CREATE VIEW hollywood.winners AS ...@@ -181,6 +194,7 @@ CREATE VIEW hollywood.winners AS
<simplelist type="inline"> <simplelist type="inline">
<member><xref linkend="sql-alterschema" endterm="sql-alterschema-title"></member> <member><xref linkend="sql-alterschema" endterm="sql-alterschema-title"></member>
<member><xref linkend="sql-dropschema" endterm="sql-dropschema-title"></member> <member><xref linkend="sql-dropschema" endterm="sql-dropschema-title"></member>
<member><xref linkend="sql-createtablespace" endterm="sql-createtablespace-title"></member>
</simplelist> </simplelist>
</refsect1> </refsect1>
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -23,6 +23,7 @@ PostgreSQL documentation ...@@ -23,6 +23,7 @@ PostgreSQL documentation
CREATE [ TEMPORARY | TEMP ] SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ] 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 ] [ 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 ] [ START [ WITH ] <replaceable class="parameter">start</replaceable> ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
[ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -193,6 +194,19 @@ SELECT * FROM <replaceable>name</replaceable>; ...@@ -193,6 +194,19 @@ SELECT * FROM <replaceable>name</replaceable>;
</para> </para>
</listitem> </listitem>
</varlistentry> </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> </variablelist>
</refsect1> </refsect1>
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -28,6 +28,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR ...@@ -28,6 +28,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
[ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ] [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ] [ WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
where <replaceable class="PARAMETER">column_constraint</replaceable> is: where <replaceable class="PARAMETER">column_constraint</replaceable> is:
...@@ -591,6 +592,18 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is: ...@@ -591,6 +592,18 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
</para> </para>
</listitem> </listitem>
</varlistentry> </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> </variablelist>
</refsect1> </refsect1>
...@@ -923,6 +936,15 @@ CREATE TABLE distributors ( ...@@ -923,6 +936,15 @@ CREATE TABLE distributors (
DROP COLUMN</>, so it seems cleaner to ignore this spec restriction. DROP COLUMN</>, so it seems cleaner to ignore this spec restriction.
</para> </para>
</refsect2> </refsect2>
<refsect2>
<title>TABLESPACE</title>
<para>
The <productname>PostgreSQL</productname> concept of tablespaces is not
standard.
</para>
</refsect2>
</refsect1> </refsect1>
...@@ -932,6 +954,7 @@ CREATE TABLE distributors ( ...@@ -932,6 +954,7 @@ CREATE TABLE distributors (
<simplelist type="inline"> <simplelist type="inline">
<member><xref linkend="sql-altertable" endterm="sql-altertable-title"></member> <member><xref linkend="sql-altertable" endterm="sql-altertable-title"></member>
<member><xref linkend="sql-droptable" endterm="sql-droptable-title"></member> <member><xref linkend="sql-droptable" endterm="sql-droptable-title"></member>
<member><xref linkend="sql-createtablespace" endterm="sql-createtablespace-title"></member>
</simplelist> </simplelist>
</refsect1> </refsect1>
</refentry> </refentry>
......
<!--
$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:
-->
<!--
$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:
-->
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -29,6 +29,10 @@ GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] } ...@@ -29,6 +29,10 @@ GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE <replaceable>dbname</replaceable> [, ...] ON DATABASE <replaceable>dbname</replaceable> [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] 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 ] } GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...] ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] 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 ] } ...@@ -87,7 +91,7 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
<para> <para>
Depending on the type of object, the initial default privileges may Depending on the type of object, the initial default privileges may
include granting some privileges to <literal>PUBLIC</literal>. 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>TEMP</> table creation privilege for databases;
<literal>EXECUTE</> privilege for functions; and <literal>EXECUTE</> privilege for functions; and
<literal>USAGE</> privilege for languages. <literal>USAGE</> privilege for languages.
...@@ -184,6 +188,12 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } ...@@ -184,6 +188,12 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
<para> <para>
For databases, allows new schemas to be created within the database. For databases, allows new schemas to be created within the database.
</para> </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> <para>
For schemas, allows new objects to be created within the schema. For schemas, allows new objects to be created within the schema.
To rename an existing object, you must own the object <emphasis>and</> To rename an existing object, you must own the object <emphasis>and</>
...@@ -412,7 +422,7 @@ GRANT <replaceable class="PARAMETER">privileges</replaceable> ...@@ -412,7 +422,7 @@ GRANT <replaceable class="PARAMETER">privileges</replaceable>
<para> <para>
The <literal>RULE</literal> privilege, and privileges on 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. <productname>PostgreSQL</productname> extensions.
</para> </para>
</refsect1> </refsect1>
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -824,6 +824,19 @@ testdb=> ...@@ -824,6 +824,19 @@ testdb=>
</varlistentry> </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> <varlistentry>
<term><literal>\dc [ <replaceable class="parameter">pattern</replaceable> ]</literal></term> <term><literal>\dc [ <replaceable class="parameter">pattern</replaceable> ]</literal></term>
<listitem> <listitem>
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -33,6 +33,12 @@ REVOKE [ GRANT OPTION FOR ] ...@@ -33,6 +33,12 @@ REVOKE [ GRANT OPTION FOR ]
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ] [ 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 ] REVOKE [ GRANT OPTION FOR ]
{ EXECUTE | ALL [ PRIVILEGES ] } { EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...] ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...]
......
<!-- reference.sgml <!-- 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 PostgreSQL Reference Manual
--> -->
...@@ -76,6 +76,7 @@ PostgreSQL Reference Manual ...@@ -76,6 +76,7 @@ PostgreSQL Reference Manual
&createSequence; &createSequence;
&createTable; &createTable;
&createTableAs; &createTableAs;
&createTableSpace;
&createTrigger; &createTrigger;
&createType; &createType;
&createUser; &createUser;
...@@ -98,6 +99,7 @@ PostgreSQL Reference Manual ...@@ -98,6 +99,7 @@ PostgreSQL Reference Manual
&dropSchema; &dropSchema;
&dropSequence; &dropSequence;
&dropTable; &dropTable;
&dropTableSpace;
&dropTrigger; &dropTrigger;
&dropType; &dropType;
&dropUser; &dropUser;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -2630,8 +2630,8 @@ heap_undo(XLogRecPtr lsn, XLogRecord *record) ...@@ -2630,8 +2630,8 @@ heap_undo(XLogRecPtr lsn, XLogRecord *record)
static void static void
out_target(char *buf, xl_heaptid *target) out_target(char *buf, xl_heaptid *target)
{ {
sprintf(buf + strlen(buf), "node %u/%u; tid %u/%u", sprintf(buf + strlen(buf), "rel %u/%u/%u; tid %u/%u",
target->node.tblNode, target->node.relNode, target->node.spcNode, target->node.dbNode, target->node.relNode,
ItemPointerGetBlockNumber(&(target->tid)), ItemPointerGetBlockNumber(&(target->tid)),
ItemPointerGetOffsetNumber(&(target->tid))); ItemPointerGetOffsetNumber(&(target->tid)));
} }
...@@ -2673,8 +2673,9 @@ heap_desc(char *buf, uint8 xl_info, char *rec) ...@@ -2673,8 +2673,9 @@ heap_desc(char *buf, uint8 xl_info, char *rec)
{ {
xl_heap_clean *xlrec = (xl_heap_clean *) rec; xl_heap_clean *xlrec = (xl_heap_clean *) rec;
sprintf(buf + strlen(buf), "clean: node %u/%u; blk %u", sprintf(buf + strlen(buf), "clean: rel %u/%u/%u; blk %u",
xlrec->node.tblNode, xlrec->node.relNode, xlrec->block); xlrec->node.spcNode, xlrec->node.dbNode,
xlrec->node.relNode, xlrec->block);
} }
else else
strcat(buf, "UNKNOWN"); strcat(buf, "UNKNOWN");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -803,8 +803,8 @@ btree_undo(XLogRecPtr lsn, XLogRecord *record)
static void static void
out_target(char *buf, xl_btreetid *target) out_target(char *buf, xl_btreetid *target)
{ {
sprintf(buf + strlen(buf), "node %u/%u; tid %u/%u", sprintf(buf + strlen(buf), "rel %u/%u/%u; tid %u/%u",
target->node.tblNode, target->node.relNode, target->node.spcNode, target->node.dbNode, target->node.relNode,
ItemPointerGetBlockNumber(&(target->tid)), ItemPointerGetBlockNumber(&(target->tid)),
ItemPointerGetOffsetNumber(&(target->tid))); ItemPointerGetOffsetNumber(&(target->tid)));
} }
...@@ -884,8 +884,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec) ...@@ -884,8 +884,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
{ {
xl_btree_delete *xlrec = (xl_btree_delete *) rec; xl_btree_delete *xlrec = (xl_btree_delete *) rec;
sprintf(buf + strlen(buf), "delete: node %u/%u; blk %u", sprintf(buf + strlen(buf), "delete: rel %u/%u/%u; blk %u",
xlrec->node.tblNode, xlrec->node.relNode, xlrec->block); xlrec->node.spcNode, xlrec->node.dbNode,
xlrec->node.relNode, xlrec->block);
break; break;
} }
case XLOG_BTREE_DELETE_PAGE: case XLOG_BTREE_DELETE_PAGE:
...@@ -903,8 +904,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec) ...@@ -903,8 +904,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
{ {
xl_btree_newroot *xlrec = (xl_btree_newroot *) rec; xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
sprintf(buf + strlen(buf), "newroot: node %u/%u; root %u lev %u", sprintf(buf + strlen(buf), "newroot: rel %u/%u/%u; root %u lev %u",
xlrec->node.tblNode, xlrec->node.relNode, xlrec->node.spcNode, xlrec->node.dbNode,
xlrec->node.relNode,
xlrec->rootblk, xlrec->level); xlrec->rootblk, xlrec->level);
break; break;
} }
...@@ -912,8 +914,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec) ...@@ -912,8 +914,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
{ {
xl_btree_newmeta *xlrec = (xl_btree_newmeta *) 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", sprintf(buf + strlen(buf), "newmeta: rel %u/%u/%u; root %u lev %u fast %u lev %u",
xlrec->node.tblNode, xlrec->node.relNode, xlrec->node.spcNode, xlrec->node.dbNode,
xlrec->node.relNode,
xlrec->meta.root, xlrec->meta.level, xlrec->meta.root, xlrec->meta.level,
xlrec->meta.fastroot, xlrec->meta.fastlevel); xlrec->meta.fastroot, xlrec->meta.fastlevel);
break; break;
...@@ -922,9 +925,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec) ...@@ -922,9 +925,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
{ {
xl_btree_newpage *xlrec = (xl_btree_newpage *) rec; xl_btree_newpage *xlrec = (xl_btree_newpage *) rec;
sprintf(buf + strlen(buf), "newpage: node %u/%u; page %u", sprintf(buf + strlen(buf), "newpage: rel %u/%u/%u; page %u",
xlrec->node.tblNode, xlrec->node.relNode, xlrec->node.spcNode, xlrec->node.dbNode,
xlrec->blkno); xlrec->node.relNode, xlrec->blkno);
break; break;
} }
default: default:
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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) ...@@ -354,7 +354,7 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode)
* though, since we are presumably running by ourselves and can't * though, since we are presumably running by ourselves and can't
* have any lock conflicts ... * 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; res->reldata.rd_lockInfo.lockRelId.relId = rnode.relNode;
hentry = (XLogRelCacheEntry *) hentry = (XLogRelCacheEntry *)
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -31,6 +31,7 @@
#include "catalog/pg_attribute.h" #include "catalog/pg_attribute.h"
#include "catalog/pg_class.h" #include "catalog/pg_class.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
#include "commands/defrem.h" #include "commands/defrem.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
...@@ -181,6 +182,7 @@ Boot_CreateStmt: ...@@ -181,6 +182,7 @@ Boot_CreateStmt:
boot_reldesc = heap_create(LexIDStr($5), boot_reldesc = heap_create(LexIDStr($5),
PG_CATALOG_NAMESPACE, PG_CATALOG_NAMESPACE,
$3 ? GLOBALTABLESPACE_OID : 0,
tupdesc, tupdesc,
$3, $3,
true, true,
...@@ -193,6 +195,7 @@ Boot_CreateStmt: ...@@ -193,6 +195,7 @@ Boot_CreateStmt:
id = heap_create_with_catalog(LexIDStr($5), id = heap_create_with_catalog(LexIDStr($5),
PG_CATALOG_NAMESPACE, PG_CATALOG_NAMESPACE,
$3 ? GLOBALTABLESPACE_OID : 0,
tupdesc, tupdesc,
RELKIND_RELATION, RELKIND_RELATION,
$3, $3,
...@@ -239,6 +242,7 @@ Boot_DeclareIndexStmt: ...@@ -239,6 +242,7 @@ Boot_DeclareIndexStmt:
DefineIndex(makeRangeVar(NULL, LexIDStr($5)), DefineIndex(makeRangeVar(NULL, LexIDStr($5)),
LexIDStr($3), LexIDStr($3),
LexIDStr($7), LexIDStr($7),
NULL,
$9, $9,
NULL, NIL, NULL, NIL,
false, false, false, false, false, false,
...@@ -255,6 +259,7 @@ Boot_DeclareUniqueIndexStmt: ...@@ -255,6 +259,7 @@ Boot_DeclareUniqueIndexStmt:
DefineIndex(makeRangeVar(NULL, LexIDStr($6)), DefineIndex(makeRangeVar(NULL, LexIDStr($6)),
LexIDStr($4), LexIDStr($4),
LexIDStr($8), LexIDStr($8),
NULL,
$10, $10,
NULL, NIL, NULL, NIL,
true, false, false, true, false, false,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# #
# Makefile for backend/catalog # 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/,\ ...@@ -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_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_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_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) pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
......
This diff is collapsed.
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -20,30 +20,48 @@ ...@@ -20,30 +20,48 @@
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
#include "miscadmin.h" #include "miscadmin.h"
#define OIDCHARS 10 /* max chars printed by %u */
/* /*
* relpath - construct path to a relation's file * relpath - construct path to a relation's file
* *
* Result is a palloc'd string. * Result is a palloc'd string.
*/ */
char * char *
relpath(RelFileNode rnode) relpath(RelFileNode rnode)
{ {
int pathlen;
char *path; char *path;
if (rnode.tblNode == (Oid) 0) /* "global tablespace" */ if (rnode.spcNode == GLOBALTABLESPACE_OID)
{ {
/* Shared system relations live in {datadir}/global */ /* Shared system relations live in {datadir}/global */
path = (char *) palloc(strlen(DataDir) + 8 + sizeof(NameData) + 1); Assert(rnode.dbNode == 0);
sprintf(path, "%s/global/%u", DataDir, rnode.relNode); 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 else
{ {
path = (char *) palloc(strlen(DataDir) + 6 + 2 * sizeof(NameData) + 3); /* All other tablespaces are accessed via symlinks */
sprintf(path, "%s/base/%u/%u", DataDir, rnode.tblNode, rnode.relNode); 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; return path;
} }
...@@ -52,23 +70,39 @@ relpath(RelFileNode rnode) ...@@ -52,23 +70,39 @@ relpath(RelFileNode rnode)
* GetDatabasePath - construct path to a database dir * GetDatabasePath - construct path to a database dir
* *
* Result is a palloc'd string. * Result is a palloc'd string.
*
* XXX this must agree with relpath()!
*/ */
char * char *
GetDatabasePath(Oid tblNode) GetDatabasePath(Oid dbNode, Oid spcNode)
{ {
int pathlen;
char *path; char *path;
if (tblNode == (Oid) 0) /* "global tablespace" */ if (spcNode == GLOBALTABLESPACE_OID)
{ {
/* Shared system relations live in {datadir}/global */ /* Shared system relations live in {datadir}/global */
path = (char *) palloc(strlen(DataDir) + 8); Assert(dbNode == 0);
sprintf(path, "%s/global", DataDir); 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 else
{ {
path = (char *) palloc(strlen(DataDir) + 6 + sizeof(NameData) + 1); /* All other tablespaces are accessed via symlinks */
sprintf(path, "%s/base/%u", DataDir, tblNode); 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; return path;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "catalog/pg_statistic.h" #include "catalog/pg_statistic.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
...@@ -203,15 +204,14 @@ SystemAttributeByName(const char *attname, bool relhasoids) ...@@ -203,15 +204,14 @@ SystemAttributeByName(const char *attname, bool relhasoids)
Relation Relation
heap_create(const char *relname, heap_create(const char *relname,
Oid relnamespace, Oid relnamespace,
Oid reltablespace,
TupleDesc tupDesc, TupleDesc tupDesc,
bool shared_relation, bool shared_relation,
bool storage_create, bool storage_create,
bool allow_system_table_mods) bool allow_system_table_mods)
{ {
Oid relid; Oid relid;
Oid dbid = shared_relation ? InvalidOid : MyDatabaseId;
bool nailme = false; bool nailme = false;
RelFileNode rnode;
Relation rel; Relation rel;
/* /*
...@@ -260,27 +260,23 @@ heap_create(const char *relname, ...@@ -260,27 +260,23 @@ heap_create(const char *relname,
relid = RelOid_pg_group; relid = RelOid_pg_group;
else if (strcmp(DatabaseRelationName, relname) == 0) else if (strcmp(DatabaseRelationName, relname) == 0)
relid = RelOid_pg_database; relid = RelOid_pg_database;
else if (strcmp(TableSpaceRelationName, relname) == 0)
relid = RelOid_pg_tablespace;
else else
relid = newoid(); relid = newoid();
} }
else else
relid = newoid(); 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. * build the relcache entry.
*/ */
rel = RelationBuildLocalRelation(relname, rel = RelationBuildLocalRelation(relname,
relnamespace, relnamespace,
tupDesc, tupDesc,
relid, dbid, relid,
rnode, reltablespace,
shared_relation,
nailme); nailme);
/* /*
...@@ -296,6 +292,16 @@ heap_create(const char *relname, ...@@ -296,6 +292,16 @@ heap_create(const char *relname,
void void
heap_storage_create(Relation rel) 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); Assert(rel->rd_smgr == NULL);
rel->rd_smgr = smgropen(rel->rd_node); rel->rd_smgr = smgropen(rel->rd_node);
smgrcreate(rel->rd_smgr, rel->rd_istemp, false); smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
...@@ -692,6 +698,7 @@ AddNewRelationType(const char *typeName, ...@@ -692,6 +698,7 @@ AddNewRelationType(const char *typeName,
Oid Oid
heap_create_with_catalog(const char *relname, heap_create_with_catalog(const char *relname,
Oid relnamespace, Oid relnamespace,
Oid reltablespace,
TupleDesc tupdesc, TupleDesc tupdesc,
char relkind, char relkind,
bool shared_relation, bool shared_relation,
...@@ -726,6 +733,7 @@ heap_create_with_catalog(const char *relname, ...@@ -726,6 +733,7 @@ heap_create_with_catalog(const char *relname,
*/ */
new_rel_desc = heap_create(relname, new_rel_desc = heap_create(relname,
relnamespace, relnamespace,
reltablespace,
tupdesc, tupdesc,
shared_relation, shared_relation,
(relkind != RELKIND_VIEW && (relkind != RELKIND_VIEW &&
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -467,6 +467,7 @@ index_create(Oid heapRelationId, ...@@ -467,6 +467,7 @@ index_create(Oid heapRelationId,
const char *indexRelationName, const char *indexRelationName,
IndexInfo *indexInfo, IndexInfo *indexInfo,
Oid accessMethodObjectId, Oid accessMethodObjectId,
Oid tableSpaceId,
Oid *classObjectId, Oid *classObjectId,
bool primary, bool primary,
bool isconstraint, bool isconstraint,
...@@ -539,6 +540,7 @@ index_create(Oid heapRelationId, ...@@ -539,6 +540,7 @@ index_create(Oid heapRelationId,
*/ */
indexRelation = heap_create(indexRelationName, indexRelation = heap_create(indexRelationName,
namespaceId, namespaceId,
tableSpaceId,
indexTupDesc, indexTupDesc,
shared_relation, shared_relation,
true, true,
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -1668,7 +1668,7 @@ InitTempTableNamespace(void)
* that access the temp namespace for my own backend skip * that access the temp namespace for my own backend skip
* permissions checks on it. * permissions checks on it.
*/ */
namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID); namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID, 0);
/* Advance command counter to make namespace visible */ /* Advance command counter to make namespace visible */
CommandCounterIncrement(); CommandCounterIncrement();
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -27,7 +27,7 @@
* --------------- * ---------------
*/ */
Oid Oid
NamespaceCreate(const char *nspName, int32 ownerSysId) NamespaceCreate(const char *nspName, int32 ownerSysId, Oid nspTablespace)
{ {
Relation nspdesc; Relation nspdesc;
HeapTuple tup; HeapTuple tup;
...@@ -59,6 +59,7 @@ NamespaceCreate(const char *nspName, int32 ownerSysId) ...@@ -59,6 +59,7 @@ NamespaceCreate(const char *nspName, int32 ownerSysId)
namestrcpy(&nname, nspName); namestrcpy(&nname, nspName);
values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname); values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(ownerSysId); values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(ownerSysId);
values[Anum_pg_namespace_nsptablespace - 1] = Int32GetDatum(nspTablespace);
nulls[Anum_pg_namespace_nspacl - 1] = 'n'; nulls[Anum_pg_namespace_nspacl - 1] = 'n';
nspdesc = heap_openr(NamespaceRelationName, RowExclusiveLock); nspdesc = heap_openr(NamespaceRelationName, RowExclusiveLock);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for backend/commands # Makefile for backend/commands
# #
# IDENTIFICATION # 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 \ ...@@ -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 \ dbcommands.o define.o explain.o functioncmds.o \
indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \ indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
portalcmds.o prepare.o proclang.o \ portalcmds.o prepare.o proclang.o \
schemacmds.o sequence.o tablecmds.o trigger.o typecmds.o user.o \ schemacmds.o sequence.o tablecmds.o tablespace.o trigger.o \
vacuum.o vacuumlazy.o variable.o view.o typecmds.o user.o vacuum.o vacuumlazy.o variable.o view.o
all: SUBSYS.o all: SUBSYS.o
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -568,6 +568,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName)
OIDNewHeap = heap_create_with_catalog(NewName, OIDNewHeap = heap_create_with_catalog(NewName,
RelationGetNamespace(OldHeap), RelationGetNamespace(OldHeap),
OldHeap->rd_rel->reltablespace,
tupdesc, tupdesc,
OldHeap->rd_rel->relkind, OldHeap->rd_rel->relkind,
OldHeap->rd_rel->relisshared, OldHeap->rd_rel->relisshared,
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.121 2004/06/10 17:55:56 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.122 2004/06/18 06:13:23 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
#include "commands/defrem.h" #include "commands/defrem.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"
#include "miscadmin.h" #include "miscadmin.h"
...@@ -64,6 +65,8 @@ static bool relationHasPrimaryKey(Relation rel); ...@@ -64,6 +65,8 @@ static bool relationHasPrimaryKey(Relation rel);
* 'indexRelationName': the name for the new index, or NULL to indicate * 'indexRelationName': the name for the new index, or NULL to indicate
* that a nonconflicting default name should be picked. * that a nonconflicting default name should be picked.
* 'accessMethodName': name of the AM to use. * 'accessMethodName': name of the AM to use.
* 'tableSpaceName': name of the tablespace to create the index in.
* NULL specifies using the same tablespace as the parent relation.
* 'attributeList': a list of IndexElem specifying columns and expressions * 'attributeList': a list of IndexElem specifying columns and expressions
* to index on. * to index on.
* 'predicate': the partial-index condition, or NULL if none. * 'predicate': the partial-index condition, or NULL if none.
...@@ -83,6 +86,7 @@ void ...@@ -83,6 +86,7 @@ void
DefineIndex(RangeVar *heapRelation, DefineIndex(RangeVar *heapRelation,
char *indexRelationName, char *indexRelationName,
char *accessMethodName, char *accessMethodName,
char *tableSpaceName,
List *attributeList, List *attributeList,
Expr *predicate, Expr *predicate,
List *rangetable, List *rangetable,
...@@ -98,6 +102,7 @@ DefineIndex(RangeVar *heapRelation, ...@@ -98,6 +102,7 @@ DefineIndex(RangeVar *heapRelation,
Oid accessMethodId; Oid accessMethodId;
Oid relationId; Oid relationId;
Oid namespaceId; Oid namespaceId;
Oid tablespaceId;
Relation rel; Relation rel;
HeapTuple tuple; HeapTuple tuple;
Form_pg_am accessMethodForm; Form_pg_am accessMethodForm;
...@@ -151,6 +156,29 @@ DefineIndex(RangeVar *heapRelation, ...@@ -151,6 +156,29 @@ DefineIndex(RangeVar *heapRelation,
get_namespace_name(namespaceId)); get_namespace_name(namespaceId));
} }
/* Determine tablespace to use */
if (tableSpaceName)
{
AclResult aclresult;
tablespaceId = get_tablespace_oid(tableSpaceName);
if (!OidIsValid(tablespaceId))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("tablespace \"%s\" does not exist",
tableSpaceName)));
/* check permissions */
aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
tableSpaceName);
} else {
/* Use the parent rel's tablespace */
tablespaceId = get_rel_tablespace(relationId);
/* Note there is no additional permission check in this path */
}
/* /*
* Select name for index if caller didn't specify * Select name for index if caller didn't specify
*/ */
...@@ -335,7 +363,7 @@ DefineIndex(RangeVar *heapRelation, ...@@ -335,7 +363,7 @@ DefineIndex(RangeVar *heapRelation,
indexRelationName, RelationGetRelationName(rel)))); indexRelationName, RelationGetRelationName(rel))));
index_create(relationId, indexRelationName, index_create(relationId, indexRelationName,
indexInfo, accessMethodId, classObjectId, indexInfo, accessMethodId, tablespaceId, classObjectId,
primary, isconstraint, primary, isconstraint,
allowSystemTableMods, skip_build); allowSystemTableMods, skip_build);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.18 2004/05/26 04:41:11 neilc Exp $ * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.19 2004/06/18 06:13:23 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
#include "commands/schemacmds.h" #include "commands/schemacmds.h"
#include "commands/tablespace.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/analyze.h" #include "parser/analyze.h"
#include "tcop/utility.h" #include "tcop/utility.h"
...@@ -41,6 +42,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) ...@@ -41,6 +42,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
const char *schemaName = stmt->schemaname; const char *schemaName = stmt->schemaname;
const char *authId = stmt->authid; const char *authId = stmt->authid;
Oid namespaceId; Oid namespaceId;
Oid tablespaceId;
List *parsetree_list; List *parsetree_list;
ListCell *parsetree_item; ListCell *parsetree_item;
const char *owner_name; const char *owner_name;
...@@ -100,8 +102,33 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) ...@@ -100,8 +102,33 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
errmsg("unacceptable schema name \"%s\"", schemaName), errmsg("unacceptable schema name \"%s\"", schemaName),
errdetail("The prefix \"pg_\" is reserved for system schemas."))); errdetail("The prefix \"pg_\" is reserved for system schemas.")));
/*
* Select default tablespace for schema. If not given, use zero
* which implies the database's default tablespace.
*/
if (stmt->tablespacename)
{
AclResult aclresult;
tablespaceId = get_tablespace_oid(stmt->tablespacename);
if (!OidIsValid(tablespaceId))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("tablespace \"%s\" does not exist",
stmt->tablespacename)));
/* check permissions */
aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
stmt->tablespacename);
} else {
tablespaceId = InvalidOid;
/* note there is no permission check in this path */
}
/* Create the schema's namespace */ /* Create the schema's namespace */
namespaceId = NamespaceCreate(schemaName, owner_userid); namespaceId = NamespaceCreate(schemaName, owner_userid, tablespaceId);
/* Advance cmd counter to make the namespace visible */ /* Advance cmd counter to make the namespace visible */
CommandCounterIncrement(); CommandCounterIncrement();
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.111 2004/05/26 04:41:11 neilc Exp $ * $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.112 2004/06/18 06:13:23 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -180,6 +180,7 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -180,6 +180,7 @@ DefineSequence(CreateSeqStmt *seq)
stmt->constraints = NIL; stmt->constraints = NIL;
stmt->hasoids = MUST_NOT_HAVE_OIDS; stmt->hasoids = MUST_NOT_HAVE_OIDS;
stmt->oncommit = ONCOMMIT_NOOP; stmt->oncommit = ONCOMMIT_NOOP;
stmt->tablespacename = seq->tablespacename;
seqoid = DefineRelation(stmt, RELKIND_SEQUENCE); seqoid = DefineRelation(stmt, RELKIND_SEQUENCE);
...@@ -1071,8 +1072,8 @@ seq_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -1071,8 +1072,8 @@ seq_redo(XLogRecPtr lsn, XLogRecord *record)
buffer = XLogReadBuffer(true, reln, 0); buffer = XLogReadBuffer(true, reln, 0);
if (!BufferIsValid(buffer)) if (!BufferIsValid(buffer))
elog(PANIC, "seq_redo: can't read block of %u/%u", elog(PANIC, "seq_redo: can't read block 0 of rel %u/%u/%u",
xlrec->node.tblNode, xlrec->node.relNode); xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
page = (Page) BufferGetPage(buffer); page = (Page) BufferGetPage(buffer);
...@@ -1114,6 +1115,6 @@ seq_desc(char *buf, uint8 xl_info, char *rec) ...@@ -1114,6 +1115,6 @@ seq_desc(char *buf, uint8 xl_info, char *rec)
return; return;
} }
sprintf(buf + strlen(buf), "node %u/%u", sprintf(buf + strlen(buf), "rel %u/%u/%u",
xlrec->node.tblNode, xlrec->node.relNode); xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.115 2004/06/10 18:34:45 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.116 2004/06/18 06:13:23 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "commands/cluster.h" #include "commands/cluster.h"
#include "commands/defrem.h" #include "commands/defrem.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
...@@ -258,6 +259,7 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -258,6 +259,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
Oid namespaceId; Oid namespaceId;
List *schema = stmt->tableElts; List *schema = stmt->tableElts;
Oid relationId; Oid relationId;
Oid tablespaceId;
Relation rel; Relation rel;
TupleDesc descriptor; TupleDesc descriptor;
List *inheritOids; List *inheritOids;
...@@ -301,6 +303,31 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -301,6 +303,31 @@ DefineRelation(CreateStmt *stmt, char relkind)
get_namespace_name(namespaceId)); get_namespace_name(namespaceId));
} }
/*
* Select tablespace to use. If not specified, use containing schema's
* default tablespace (which may in turn default to database's default).
*/
if (stmt->tablespacename)
{
AclResult aclresult;
tablespaceId = get_tablespace_oid(stmt->tablespacename);
if (!OidIsValid(tablespaceId))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("tablespace \"%s\" does not exist",
stmt->tablespacename)));
/* check permissions */
aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
stmt->tablespacename);
} else {
tablespaceId = get_namespace_tablespace(namespaceId);
/* note no permission check on tablespace in this case */
}
/* /*
* Look up inheritance ancestors and generate relation schema, * Look up inheritance ancestors and generate relation schema,
* including inherited attributes. * including inherited attributes.
...@@ -379,6 +406,7 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -379,6 +406,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
relationId = heap_create_with_catalog(relname, relationId = heap_create_with_catalog(relname,
namespaceId, namespaceId,
tablespaceId,
descriptor, descriptor,
relkind, relkind,
false, false,
...@@ -3521,6 +3549,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, ...@@ -3521,6 +3549,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
DefineIndex(stmt->relation, /* relation */ DefineIndex(stmt->relation, /* relation */
stmt->idxname, /* index name */ stmt->idxname, /* index name */
stmt->accessMethod, /* am name */ stmt->accessMethod, /* am name */
stmt->tableSpace,
stmt->indexParams, /* parameters */ stmt->indexParams, /* parameters */
(Expr *) stmt->whereClause, (Expr *) stmt->whereClause,
stmt->rangetable, stmt->rangetable,
...@@ -5272,6 +5301,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent) ...@@ -5272,6 +5301,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
*/ */
toast_relid = heap_create_with_catalog(toast_relname, toast_relid = heap_create_with_catalog(toast_relname,
PG_TOAST_NAMESPACE, PG_TOAST_NAMESPACE,
rel->rd_rel->reltablespace,
tupdesc, tupdesc,
RELKIND_TOASTVALUE, RELKIND_TOASTVALUE,
shared_relation, shared_relation,
...@@ -5309,7 +5339,9 @@ AlterTableCreateToastTable(Oid relOid, bool silent) ...@@ -5309,7 +5339,9 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
classObjectId[1] = INT4_BTREE_OPS_OID; classObjectId[1] = INT4_BTREE_OPS_OID;
toast_idxid = index_create(toast_relid, toast_idxname, indexInfo, toast_idxid = index_create(toast_relid, toast_idxname, indexInfo,
BTREE_AM_OID, classObjectId, BTREE_AM_OID,
rel->rd_rel->reltablespace,
classObjectId,
true, false, true, false); true, false, true, false);
/* /*
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.59 2004/06/10 17:55:56 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.60 2004/06/18 06:13:23 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -1110,8 +1110,8 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) ...@@ -1110,8 +1110,8 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
errmsg("composite type must have at least one attribute"))); errmsg("composite type must have at least one attribute")));
/* /*
* now create the parameters for keys/inheritance etc. All of them are * now set the parameters for keys/inheritance etc. All of these
* nil... * are uninteresting for composite types...
*/ */
createStmt->relation = (RangeVar *) typevar; createStmt->relation = (RangeVar *) typevar;
createStmt->tableElts = coldeflist; createStmt->tableElts = coldeflist;
...@@ -1119,6 +1119,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) ...@@ -1119,6 +1119,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
createStmt->constraints = NIL; createStmt->constraints = NIL;
createStmt->hasoids = MUST_NOT_HAVE_OIDS; createStmt->hasoids = MUST_NOT_HAVE_OIDS;
createStmt->oncommit = ONCOMMIT_NOOP; createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL;
/* /*
* finally create the relation... * finally create the relation...
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.82 2004/05/26 04:41:13 neilc Exp $ * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.83 2004/06/18 06:13:23 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -134,8 +134,8 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) ...@@ -134,8 +134,8 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
else else
{ {
/* /*
* now create the parameters for keys/inheritance etc. All of them * now set the parameters for keys/inheritance etc. All of these
* are nil... * are uninteresting for views...
*/ */
createStmt->relation = (RangeVar *) relation; createStmt->relation = (RangeVar *) relation;
createStmt->tableElts = attrList; createStmt->tableElts = attrList;
...@@ -143,6 +143,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) ...@@ -143,6 +143,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
createStmt->constraints = NIL; createStmt->constraints = NIL;
createStmt->hasoids = MUST_NOT_HAVE_OIDS; createStmt->hasoids = MUST_NOT_HAVE_OIDS;
createStmt->oncommit = ONCOMMIT_NOOP; createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL;
/* /*
* finally create the relation (this will error out if there's an * finally create the relation (this will error out if there's an
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.233 2004/05/30 23:40:26 neilc Exp $ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.234 2004/06/18 06:13:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -779,6 +779,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly) ...@@ -779,6 +779,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
intoRelationId = heap_create_with_catalog(intoName, intoRelationId = heap_create_with_catalog(intoName,
namespaceId, namespaceId,
InvalidOid,
tupdesc, tupdesc,
RELKIND_RELATION, RELKIND_RELATION,
false, false,
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.285 2004/06/09 19:08:15 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.286 2004/06/18 06:13:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1753,6 +1753,7 @@ _copyCreateStmt(CreateStmt *from) ...@@ -1753,6 +1753,7 @@ _copyCreateStmt(CreateStmt *from)
COPY_NODE_FIELD(constraints); COPY_NODE_FIELD(constraints);
COPY_SCALAR_FIELD(hasoids); COPY_SCALAR_FIELD(hasoids);
COPY_SCALAR_FIELD(oncommit); COPY_SCALAR_FIELD(oncommit);
COPY_STRING_FIELD(tablespacename);
return newnode; return newnode;
} }
...@@ -1836,6 +1837,7 @@ _copyIndexStmt(IndexStmt *from) ...@@ -1836,6 +1837,7 @@ _copyIndexStmt(IndexStmt *from)
COPY_STRING_FIELD(idxname); COPY_STRING_FIELD(idxname);
COPY_NODE_FIELD(relation); COPY_NODE_FIELD(relation);
COPY_STRING_FIELD(accessMethod); COPY_STRING_FIELD(accessMethod);
COPY_STRING_FIELD(tableSpace);
COPY_NODE_FIELD(indexParams); COPY_NODE_FIELD(indexParams);
COPY_NODE_FIELD(whereClause); COPY_NODE_FIELD(whereClause);
COPY_NODE_FIELD(rangetable); COPY_NODE_FIELD(rangetable);
...@@ -2146,6 +2148,7 @@ _copyCreateSeqStmt(CreateSeqStmt *from) ...@@ -2146,6 +2148,7 @@ _copyCreateSeqStmt(CreateSeqStmt *from)
COPY_NODE_FIELD(sequence); COPY_NODE_FIELD(sequence);
COPY_NODE_FIELD(options); COPY_NODE_FIELD(options);
COPY_STRING_FIELD(tablespacename);
return newnode; return newnode;
} }
...@@ -2193,6 +2196,28 @@ _copyVariableResetStmt(VariableResetStmt *from) ...@@ -2193,6 +2196,28 @@ _copyVariableResetStmt(VariableResetStmt *from)
return newnode; return newnode;
} }
static CreateTableSpaceStmt *
_copyCreateTableSpaceStmt(CreateTableSpaceStmt *from)
{
CreateTableSpaceStmt *newnode = makeNode(CreateTableSpaceStmt);
COPY_STRING_FIELD(tablespacename);
COPY_STRING_FIELD(owner);
COPY_STRING_FIELD(location);
return newnode;
}
static DropTableSpaceStmt *
_copyDropTableSpaceStmt(DropTableSpaceStmt *from)
{
DropTableSpaceStmt *newnode = makeNode(DropTableSpaceStmt);
COPY_STRING_FIELD(tablespacename);
return newnode;
}
static CreateTrigStmt * static CreateTrigStmt *
_copyCreateTrigStmt(CreateTrigStmt *from) _copyCreateTrigStmt(CreateTrigStmt *from)
{ {
...@@ -2371,6 +2396,7 @@ _copyCreateSchemaStmt(CreateSchemaStmt *from) ...@@ -2371,6 +2396,7 @@ _copyCreateSchemaStmt(CreateSchemaStmt *from)
COPY_STRING_FIELD(schemaname); COPY_STRING_FIELD(schemaname);
COPY_STRING_FIELD(authid); COPY_STRING_FIELD(authid);
COPY_STRING_FIELD(tablespacename);
COPY_NODE_FIELD(schemaElts); COPY_NODE_FIELD(schemaElts);
return newnode; return newnode;
...@@ -2914,6 +2940,12 @@ copyObject(void *from) ...@@ -2914,6 +2940,12 @@ copyObject(void *from)
case T_VariableResetStmt: case T_VariableResetStmt:
retval = _copyVariableResetStmt(from); retval = _copyVariableResetStmt(from);
break; break;
case T_CreateTableSpaceStmt:
retval = _copyCreateTableSpaceStmt(from);
break;
case T_DropTableSpaceStmt:
retval = _copyDropTableSpaceStmt(from);
break;
case T_CreateTrigStmt: case T_CreateTrigStmt:
retval = _copyCreateTrigStmt(from); retval = _copyCreateTrigStmt(from);
break; break;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.224 2004/06/09 19:08:15 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.225 2004/06/18 06:13:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -835,6 +835,7 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b) ...@@ -835,6 +835,7 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
COMPARE_NODE_FIELD(constraints); COMPARE_NODE_FIELD(constraints);
COMPARE_SCALAR_FIELD(hasoids); COMPARE_SCALAR_FIELD(hasoids);
COMPARE_SCALAR_FIELD(oncommit); COMPARE_SCALAR_FIELD(oncommit);
COMPARE_STRING_FIELD(tablespacename);
return true; return true;
} }
...@@ -904,6 +905,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b) ...@@ -904,6 +905,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
COMPARE_STRING_FIELD(idxname); COMPARE_STRING_FIELD(idxname);
COMPARE_NODE_FIELD(relation); COMPARE_NODE_FIELD(relation);
COMPARE_STRING_FIELD(accessMethod); COMPARE_STRING_FIELD(accessMethod);
COMPARE_STRING_FIELD(tableSpace);
COMPARE_NODE_FIELD(indexParams); COMPARE_NODE_FIELD(indexParams);
COMPARE_NODE_FIELD(whereClause); COMPARE_NODE_FIELD(whereClause);
COMPARE_NODE_FIELD(rangetable); COMPARE_NODE_FIELD(rangetable);
...@@ -1164,6 +1166,7 @@ _equalCreateSeqStmt(CreateSeqStmt *a, CreateSeqStmt *b) ...@@ -1164,6 +1166,7 @@ _equalCreateSeqStmt(CreateSeqStmt *a, CreateSeqStmt *b)
{ {
COMPARE_NODE_FIELD(sequence); COMPARE_NODE_FIELD(sequence);
COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(options);
COMPARE_STRING_FIELD(tablespacename);
return true; return true;
} }
...@@ -1203,6 +1206,24 @@ _equalVariableResetStmt(VariableResetStmt *a, VariableResetStmt *b) ...@@ -1203,6 +1206,24 @@ _equalVariableResetStmt(VariableResetStmt *a, VariableResetStmt *b)
return true; return true;
} }
static bool
_equalCreateTableSpaceStmt(CreateTableSpaceStmt *a, CreateTableSpaceStmt *b)
{
COMPARE_STRING_FIELD(tablespacename);
COMPARE_STRING_FIELD(owner);
COMPARE_STRING_FIELD(location);
return true;
}
static bool
_equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b)
{
COMPARE_STRING_FIELD(tablespacename);
return true;
}
static bool static bool
_equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b) _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
{ {
...@@ -1352,6 +1373,7 @@ _equalCreateSchemaStmt(CreateSchemaStmt *a, CreateSchemaStmt *b) ...@@ -1352,6 +1373,7 @@ _equalCreateSchemaStmt(CreateSchemaStmt *a, CreateSchemaStmt *b)
{ {
COMPARE_STRING_FIELD(schemaname); COMPARE_STRING_FIELD(schemaname);
COMPARE_STRING_FIELD(authid); COMPARE_STRING_FIELD(authid);
COMPARE_STRING_FIELD(tablespacename);
COMPARE_NODE_FIELD(schemaElts); COMPARE_NODE_FIELD(schemaElts);
return true; return true;
...@@ -2052,6 +2074,12 @@ equal(void *a, void *b) ...@@ -2052,6 +2074,12 @@ equal(void *a, void *b)
case T_VariableResetStmt: case T_VariableResetStmt:
retval = _equalVariableResetStmt(a, b); retval = _equalVariableResetStmt(a, b);
break; break;
case T_CreateTableSpaceStmt:
retval = _equalCreateTableSpaceStmt(a, b);
break;
case T_DropTableSpaceStmt:
retval = _equalDropTableSpaceStmt(a, b);
break;
case T_CreateTrigStmt: case T_CreateTrigStmt:
retval = _equalCreateTrigStmt(a, b); retval = _equalCreateTrigStmt(a, b);
break; break;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.239 2004/06/09 19:08:15 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.240 2004/06/18 06:13:28 tgl Exp $
* *
* NOTES * NOTES
* Every node type that can appear in stored rules' parsetrees *must* * Every node type that can appear in stored rules' parsetrees *must*
...@@ -1128,7 +1128,7 @@ _outInClauseInfo(StringInfo str, InClauseInfo *node) ...@@ -1128,7 +1128,7 @@ _outInClauseInfo(StringInfo str, InClauseInfo *node)
static void static void
_outCreateStmt(StringInfo str, CreateStmt *node) _outCreateStmt(StringInfo str, CreateStmt *node)
{ {
WRITE_NODE_TYPE("CREATE"); WRITE_NODE_TYPE("CREATESTMT");
WRITE_NODE_FIELD(relation); WRITE_NODE_FIELD(relation);
WRITE_NODE_FIELD(tableElts); WRITE_NODE_FIELD(tableElts);
...@@ -1136,16 +1136,18 @@ _outCreateStmt(StringInfo str, CreateStmt *node) ...@@ -1136,16 +1136,18 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
WRITE_NODE_FIELD(constraints); WRITE_NODE_FIELD(constraints);
WRITE_ENUM_FIELD(hasoids, ContainsOids); WRITE_ENUM_FIELD(hasoids, ContainsOids);
WRITE_ENUM_FIELD(oncommit, OnCommitAction); WRITE_ENUM_FIELD(oncommit, OnCommitAction);
WRITE_STRING_FIELD(tablespacename);
} }
static void static void
_outIndexStmt(StringInfo str, IndexStmt *node) _outIndexStmt(StringInfo str, IndexStmt *node)
{ {
WRITE_NODE_TYPE("INDEX"); WRITE_NODE_TYPE("INDEXSTMT");
WRITE_STRING_FIELD(idxname); WRITE_STRING_FIELD(idxname);
WRITE_NODE_FIELD(relation); WRITE_NODE_FIELD(relation);
WRITE_STRING_FIELD(accessMethod); WRITE_STRING_FIELD(accessMethod);
WRITE_STRING_FIELD(tableSpace);
WRITE_NODE_FIELD(indexParams); WRITE_NODE_FIELD(indexParams);
WRITE_NODE_FIELD(whereClause); WRITE_NODE_FIELD(whereClause);
WRITE_NODE_FIELD(rangetable); WRITE_NODE_FIELD(rangetable);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.305 2004/06/10 17:55:58 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.306 2004/06/18 06:13:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -874,6 +874,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt, ...@@ -874,6 +874,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
seqstmt = makeNode(CreateSeqStmt); seqstmt = makeNode(CreateSeqStmt);
seqstmt->sequence = makeRangeVar(snamespace, sname); seqstmt->sequence = makeRangeVar(snamespace, sname);
seqstmt->options = NIL; seqstmt->options = NIL;
seqstmt->tablespacename = NULL;
cxt->blist = lappend(cxt->blist, seqstmt); cxt->blist = lappend(cxt->blist, seqstmt);
...@@ -1199,6 +1200,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt) ...@@ -1199,6 +1200,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
index->relation = cxt->relation; index->relation = cxt->relation;
index->accessMethod = DEFAULT_INDEX_TYPE; index->accessMethod = DEFAULT_INDEX_TYPE;
index->tableSpace = NULL;
index->indexParams = NIL; index->indexParams = NIL;
index->whereClause = NULL; index->whereClause = NULL;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.461 2004/06/09 19:08:17 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.462 2004/06/18 06:13:31 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -136,12 +136,12 @@ static void doNegateFloat(Value *v); ...@@ -136,12 +136,12 @@ static void doNegateFloat(Value *v);
AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt
CreateSchemaStmt CreateSeqStmt CreateStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
CreateAssertStmt CreateTrigStmt CreateUserStmt CreateAssertStmt CreateTrigStmt CreateUserStmt
CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt
DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt
DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt
DropUserStmt DropdbStmt ExplainStmt FetchStmt DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt
LockStmt NotifyStmt ExplainableStmt PreparableStmt LockStmt NotifyStmt ExplainableStmt PreparableStmt
CreateFunctionStmt ReindexStmt RemoveAggrStmt CreateFunctionStmt ReindexStmt RemoveAggrStmt
...@@ -324,6 +324,7 @@ static void doNegateFloat(Value *v); ...@@ -324,6 +324,7 @@ static void doNegateFloat(Value *v);
%type <list> constraints_set_list %type <list> constraints_set_list
%type <boolean> constraints_set_mode %type <boolean> constraints_set_mode
%type <str> OptTableSpace OptTableSpaceOwner
/* /*
...@@ -398,7 +399,7 @@ static void doNegateFloat(Value *v); ...@@ -398,7 +399,7 @@ static void doNegateFloat(Value *v);
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SYSID STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SYSID
TABLE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
TO TOAST TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TO TOAST TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
TRUNCATE TRUSTED TYPE_P TRUNCATE TRUSTED TYPE_P
...@@ -513,6 +514,7 @@ stmt : ...@@ -513,6 +514,7 @@ stmt :
| CreateSchemaStmt | CreateSchemaStmt
| CreateSeqStmt | CreateSeqStmt
| CreateStmt | CreateStmt
| CreateTableSpaceStmt
| CreateTrigStmt | CreateTrigStmt
| CreateUserStmt | CreateUserStmt
| CreatedbStmt | CreatedbStmt
...@@ -527,6 +529,7 @@ stmt : ...@@ -527,6 +529,7 @@ stmt :
| DropPLangStmt | DropPLangStmt
| DropRuleStmt | DropRuleStmt
| DropStmt | DropStmt
| DropTableSpaceStmt
| DropTrigStmt | DropTrigStmt
| DropUserStmt | DropUserStmt
| DropdbStmt | DropdbStmt
...@@ -781,7 +784,7 @@ DropGroupStmt: ...@@ -781,7 +784,7 @@ DropGroupStmt:
*****************************************************************************/ *****************************************************************************/
CreateSchemaStmt: CreateSchemaStmt:
CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptSchemaEltList CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptTableSpace OptSchemaEltList
{ {
CreateSchemaStmt *n = makeNode(CreateSchemaStmt); CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* One can omit the schema name or the authorization id. */ /* One can omit the schema name or the authorization id. */
...@@ -790,16 +793,18 @@ CreateSchemaStmt: ...@@ -790,16 +793,18 @@ CreateSchemaStmt:
else else
n->schemaname = $5; n->schemaname = $5;
n->authid = $5; n->authid = $5;
n->schemaElts = $6; n->tablespacename = $6;
n->schemaElts = $7;
$$ = (Node *)n; $$ = (Node *)n;
} }
| CREATE SCHEMA ColId OptSchemaEltList | CREATE SCHEMA ColId OptTableSpace OptSchemaEltList
{ {
CreateSchemaStmt *n = makeNode(CreateSchemaStmt); CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* ...but not both */ /* ...but not both */
n->schemaname = $3; n->schemaname = $3;
n->authid = NULL; n->authid = NULL;
n->schemaElts = $4; n->tablespacename = $4;
n->schemaElts = $5;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -1464,7 +1469,7 @@ opt_using: ...@@ -1464,7 +1469,7 @@ opt_using:
*****************************************************************************/ *****************************************************************************/
CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
OptInherit OptWithOids OnCommitOption OptInherit OptWithOids OnCommitOption OptTableSpace
{ {
CreateStmt *n = makeNode(CreateStmt); CreateStmt *n = makeNode(CreateStmt);
$4->istemp = $2; $4->istemp = $2;
...@@ -1474,10 +1479,11 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' ...@@ -1474,10 +1479,11 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->constraints = NIL; n->constraints = NIL;
n->hasoids = $9; n->hasoids = $9;
n->oncommit = $10; n->oncommit = $10;
n->tablespacename = $11;
$$ = (Node *)n; $$ = (Node *)n;
} }
| CREATE OptTemp TABLE qualified_name OF qualified_name | CREATE OptTemp TABLE qualified_name OF qualified_name
'(' OptTableElementList ')' OptWithOids OnCommitOption '(' OptTableElementList ')' OptWithOids OnCommitOption OptTableSpace
{ {
/* SQL99 CREATE TABLE OF <UDT> (cols) seems to be satisfied /* SQL99 CREATE TABLE OF <UDT> (cols) seems to be satisfied
* by our inheritance capabilities. Let's try it... * by our inheritance capabilities. Let's try it...
...@@ -1490,6 +1496,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' ...@@ -1490,6 +1496,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->constraints = NIL; n->constraints = NIL;
n->hasoids = $10; n->hasoids = $10;
n->oncommit = $11; n->oncommit = $11;
n->tablespacename = $12;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -1901,6 +1908,10 @@ OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; } ...@@ -1901,6 +1908,10 @@ OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; }
| /*EMPTY*/ { $$ = ONCOMMIT_NOOP; } | /*EMPTY*/ { $$ = ONCOMMIT_NOOP; }
; ;
OptTableSpace: TABLESPACE name { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; }
;
/* /*
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
...@@ -1979,12 +1990,13 @@ CreateAsElement: ...@@ -1979,12 +1990,13 @@ CreateAsElement:
*****************************************************************************/ *****************************************************************************/
CreateSeqStmt: CreateSeqStmt:
CREATE OptTemp SEQUENCE qualified_name OptSeqList CREATE OptTemp SEQUENCE qualified_name OptSeqList OptTableSpace
{ {
CreateSeqStmt *n = makeNode(CreateSeqStmt); CreateSeqStmt *n = makeNode(CreateSeqStmt);
$4->istemp = $2; $4->istemp = $2;
n->sequence = $4; n->sequence = $4;
n->options = $5; n->options = $5;
n->tablespacename = $6;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -2134,6 +2146,45 @@ opt_procedural: ...@@ -2134,6 +2146,45 @@ opt_procedural:
| /*EMPTY*/ {} | /*EMPTY*/ {}
; ;
/*****************************************************************************
*
* QUERY:
* CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/'
*
*****************************************************************************/
CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst
{
CreateTableSpaceStmt *n = makeNode(CreateTableSpaceStmt);
n->tablespacename = $3;
n->owner = $4;
n->location = $6;
$$ = (Node *) n;
}
;
OptTableSpaceOwner: OWNER name { $$ = $2; }
| /*EMPTY */ { $$ = NULL; }
;
/*****************************************************************************
*
* QUERY :
* DROP TABLESPACE <tablespace>
*
* No need for drop behaviour as we cannot implement dependencies for
* objects in other databases; we can only support RESTRICT.
*
****************************************************************************/
DropTableSpaceStmt: DROP TABLESPACE name
{
DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt);
n->tablespacename = $3;
$$ = (Node *) n;
}
;
/***************************************************************************** /*****************************************************************************
* *
* QUERIES : * QUERIES :
...@@ -3026,6 +3077,13 @@ privilege_target: ...@@ -3026,6 +3077,13 @@ privilege_target:
n->objs = $2; n->objs = $2;
$$ = n; $$ = n;
} }
| TABLESPACE name_list
{
PrivTarget *n = makeNode(PrivTarget);
n->objtype = ACL_OBJECT_TABLESPACE;
n->objs = $2;
$$ = n;
}
; ;
...@@ -3092,12 +3150,14 @@ function_with_argtypes: ...@@ -3092,12 +3150,14 @@ function_with_argtypes:
* QUERY: * QUERY:
* create index <indexname> on <relname> * create index <indexname> on <relname>
* [ using <access> ] "(" ( <col> [ using <opclass> ] )+ ")" * [ using <access> ] "(" ( <col> [ using <opclass> ] )+ ")"
* [ where <predicate> ] * [ tablespace <tablespacename> ] [ where <predicate> ]
* *
* Note: we cannot put TABLESPACE clause after WHERE clause unless we are
* willing to make TABLESPACE a fully reserved word.
*****************************************************************************/ *****************************************************************************/
IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name
access_method_clause '(' index_params ')' where_clause access_method_clause '(' index_params ')' OptTableSpace where_clause
{ {
IndexStmt *n = makeNode(IndexStmt); IndexStmt *n = makeNode(IndexStmt);
n->unique = $2; n->unique = $2;
...@@ -3105,7 +3165,8 @@ IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name ...@@ -3105,7 +3165,8 @@ IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name
n->relation = $6; n->relation = $6;
n->accessMethod = $7; n->accessMethod = $7;
n->indexParams = $9; n->indexParams = $9;
n->whereClause = $11; n->tableSpace = $11;
n->whereClause = $12;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -3896,7 +3957,15 @@ createdb_opt_list: ...@@ -3896,7 +3957,15 @@ createdb_opt_list:
; ;
createdb_opt_item: createdb_opt_item:
LOCATION opt_equal Sconst TABLESPACE opt_equal name
{
$$ = makeDefElem("tablespace", (Node *)makeString($3));
}
| TABLESPACE opt_equal DEFAULT
{
$$ = makeDefElem("tablespace", NULL);
}
| LOCATION opt_equal Sconst
{ {
$$ = makeDefElem("location", (Node *)makeString($3)); $$ = makeDefElem("location", (Node *)makeString($3));
} }
...@@ -7565,6 +7634,7 @@ unreserved_keyword: ...@@ -7565,6 +7634,7 @@ unreserved_keyword:
| STORAGE | STORAGE
| SYSID | SYSID
| STRICT_P | STRICT_P
| TABLESPACE
| TEMP | TEMP
| TEMPLATE | TEMPLATE
| TEMPORARY | TEMPORARY
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.149 2004/04/21 00:34:18 momjian Exp $ * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.150 2004/06/18 06:13:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -297,6 +297,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -297,6 +297,7 @@ static const ScanKeyword ScanKeywords[] = {
{"substring", SUBSTRING}, {"substring", SUBSTRING},
{"sysid", SYSID}, {"sysid", SYSID},
{"table", TABLE}, {"table", TABLE},
{"tablespace", TABLESPACE},
{"temp", TEMP}, {"temp", TEMP},
{"template", TEMPLATE}, {"template", TEMPLATE},
{"temporary", TEMPORARY}, {"temporary", TEMPORARY},
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.170 2004/06/11 16:43:23 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.171 2004/06/18 06:13:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -832,9 +832,10 @@ AtEOXact_Buffers(bool isCommit) ...@@ -832,9 +832,10 @@ AtEOXact_Buffers(bool isCommit)
if (isCommit) if (isCommit)
elog(WARNING, elog(WARNING,
"buffer refcount leak: [%03d] " "buffer refcount leak: [%03d] "
"(rel=%u/%u, blockNum=%u, flags=0x%x, refcount=%u %d)", "(rel=%u/%u/%u, blockNum=%u, flags=0x%x, refcount=%u %d)",
i, i,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.rnode.relNode,
buf->tag.blockNum, buf->flags, buf->tag.blockNum, buf->flags,
buf->refcount, PrivateRefCount[i]); buf->refcount, PrivateRefCount[i]);
...@@ -1137,9 +1138,10 @@ recheck: ...@@ -1137,9 +1138,10 @@ recheck:
{ {
/* the sole pin should be ours */ /* the sole pin should be ours */
if (bufHdr->refcount != 1 || PrivateRefCount[i - 1] == 0) if (bufHdr->refcount != 1 || PrivateRefCount[i - 1] == 0)
elog(FATAL, "block %u of %u/%u is still referenced (private %d, global %u)", elog(FATAL, "block %u of %u/%u/%u is still referenced (private %d, global %u)",
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
bufHdr->tag.rnode.tblNode, bufHdr->tag.rnode.spcNode,
bufHdr->tag.rnode.dbNode,
bufHdr->tag.rnode.relNode, bufHdr->tag.rnode.relNode,
PrivateRefCount[i - 1], bufHdr->refcount); PrivateRefCount[i - 1], bufHdr->refcount);
/* Make sure it will be released */ /* Make sure it will be released */
...@@ -1180,13 +1182,7 @@ DropBuffers(Oid dbid) ...@@ -1180,13 +1182,7 @@ DropBuffers(Oid dbid)
{ {
bufHdr = &BufferDescriptors[i - 1]; bufHdr = &BufferDescriptors[i - 1];
recheck: recheck:
if (bufHdr->tag.rnode.dbNode == dbid)
/*
* We know that currently database OID is tblNode but this
* probably will be changed in future and this func will be used
* to drop tablespace buffers.
*/
if (bufHdr->tag.rnode.tblNode == dbid)
{ {
/* /*
* If there is I/O in progress, better wait till it's done; * If there is I/O in progress, better wait till it's done;
...@@ -1243,10 +1239,11 @@ PrintBufferDescs(void) ...@@ -1243,10 +1239,11 @@ PrintBufferDescs(void)
for (i = 0; i < NBuffers; ++i, ++buf) for (i = 0; i < NBuffers; ++i, ++buf)
{ {
elog(LOG, elog(LOG,
"[%02d] (freeNext=%d, freePrev=%d, rel=%u/%u, " "[%02d] (freeNext=%d, freePrev=%d, rel=%u/%u/%u, "
"blockNum=%u, flags=0x%x, refcount=%u %d)", "blockNum=%u, flags=0x%x, refcount=%u %d)",
i, buf->freeNext, buf->freePrev, i, buf->freeNext, buf->freePrev,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.rnode.relNode,
buf->tag.blockNum, buf->flags, buf->tag.blockNum, buf->flags,
buf->refcount, PrivateRefCount[i]); buf->refcount, PrivateRefCount[i]);
} }
...@@ -1257,9 +1254,9 @@ PrintBufferDescs(void) ...@@ -1257,9 +1254,9 @@ PrintBufferDescs(void)
/* interactive backend */ /* interactive backend */
for (i = 0; i < NBuffers; ++i, ++buf) for (i = 0; i < NBuffers; ++i, ++buf)
{ {
printf("[%-2d] (%u/%u, %u) flags=0x%x, refcount=%u %d)\n", printf("[%-2d] (%u/%u/%u, %u) flags=0x%x, refcount=%u %d)\n",
i, buf->tag.rnode.tblNode, buf->tag.rnode.relNode, i, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.blockNum, buf->tag.rnode.relNode, buf->tag.blockNum,
buf->flags, buf->refcount, PrivateRefCount[i]); buf->flags, buf->refcount, PrivateRefCount[i]);
} }
} }
...@@ -1278,10 +1275,11 @@ PrintPinnedBufs(void) ...@@ -1278,10 +1275,11 @@ PrintPinnedBufs(void)
{ {
if (PrivateRefCount[i] > 0) if (PrivateRefCount[i] > 0)
elog(WARNING, elog(WARNING,
"[%02d] (freeNext=%d, freePrev=%d, rel=%u/%u, " "[%02d] (freeNext=%d, freePrev=%d, rel=%u/%u/%u, "
"blockNum=%u, flags=0x%x, refcount=%u %d)", "blockNum=%u, flags=0x%x, refcount=%u %d)",
i, buf->freeNext, buf->freePrev, i, buf->freeNext, buf->freePrev,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.rnode.relNode,
buf->tag.blockNum, buf->flags, buf->tag.blockNum, buf->flags,
buf->refcount, PrivateRefCount[i]); buf->refcount, PrivateRefCount[i]);
} }
...@@ -1464,11 +1462,11 @@ IncrBufferRefCount_Debug(char *file, int line, Buffer buffer) ...@@ -1464,11 +1462,11 @@ IncrBufferRefCount_Debug(char *file, int line, Buffer buffer)
BufferDesc *buf = &BufferDescriptors[buffer - 1]; BufferDesc *buf = &BufferDescriptors[buffer - 1];
fprintf(stderr, fprintf(stderr,
"PIN(Incr) %d rel = %u/%u, blockNum = %u, " "PIN(Incr) %d rel = %u/%u/%u, blockNum = %u, "
"refcount = %d, file: %s, line: %d\n", "refcount = %d, file: %s, line: %d\n",
buffer, buffer,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.blockNum, buf->tag.rnode.relNode, buf->tag.blockNum,
PrivateRefCount[buffer - 1], file, line); PrivateRefCount[buffer - 1], file, line);
} }
} }
...@@ -1484,11 +1482,11 @@ ReleaseBuffer_Debug(char *file, int line, Buffer buffer) ...@@ -1484,11 +1482,11 @@ ReleaseBuffer_Debug(char *file, int line, Buffer buffer)
BufferDesc *buf = &BufferDescriptors[buffer - 1]; BufferDesc *buf = &BufferDescriptors[buffer - 1];
fprintf(stderr, fprintf(stderr,
"UNPIN(Rel) %d rel = %u/%u, blockNum = %u, " "UNPIN(Rel) %d rel = %u/%u/%u, blockNum = %u, "
"refcount = %d, file: %s, line: %d\n", "refcount = %d, file: %s, line: %d\n",
buffer, buffer,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.blockNum, buf->tag.rnode.relNode, buf->tag.blockNum,
PrivateRefCount[buffer - 1], file, line); PrivateRefCount[buffer - 1], file, line);
} }
} }
...@@ -1513,11 +1511,11 @@ ReleaseAndReadBuffer_Debug(char *file, ...@@ -1513,11 +1511,11 @@ ReleaseAndReadBuffer_Debug(char *file,
BufferDesc *buf = &BufferDescriptors[buffer - 1]; BufferDesc *buf = &BufferDescriptors[buffer - 1];
fprintf(stderr, fprintf(stderr,
"UNPIN(Rel&Rd) %d rel = %u/%u, blockNum = %u, " "UNPIN(Rel&Rd) %d rel = %u/%u/%u, blockNum = %u, "
"refcount = %d, file: %s, line: %d\n", "refcount = %d, file: %s, line: %d\n",
buffer, buffer,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.blockNum, buf->tag.rnode.relNode, buf->tag.blockNum,
PrivateRefCount[buffer - 1], file, line); PrivateRefCount[buffer - 1], file, line);
} }
if (ShowPinTrace && BufferIsLocal(buffer) && is_userbuffer(buffer)) if (ShowPinTrace && BufferIsLocal(buffer) && is_userbuffer(buffer))
...@@ -1525,11 +1523,11 @@ ReleaseAndReadBuffer_Debug(char *file, ...@@ -1525,11 +1523,11 @@ ReleaseAndReadBuffer_Debug(char *file,
BufferDesc *buf = &BufferDescriptors[b - 1]; BufferDesc *buf = &BufferDescriptors[b - 1];
fprintf(stderr, fprintf(stderr,
"PIN(Rel&Rd) %d rel = %u/%u, blockNum = %u, " "PIN(Rel&Rd) %d rel = %u/%u/%u, blockNum = %u, "
"refcount = %d, file: %s, line: %d\n", "refcount = %d, file: %s, line: %d\n",
b, b,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.blockNum, buf->tag.rnode.relNode, buf->tag.blockNum,
PrivateRefCount[b - 1], file, line); PrivateRefCount[b - 1], file, line);
} }
return b; return b;
...@@ -1890,9 +1888,10 @@ AbortBufferIO(void) ...@@ -1890,9 +1888,10 @@ AbortBufferIO(void)
{ {
ereport(WARNING, ereport(WARNING,
(errcode(ERRCODE_IO_ERROR), (errcode(ERRCODE_IO_ERROR),
errmsg("could not write block %u of %u/%u", errmsg("could not write block %u of %u/%u/%u",
buf->tag.blockNum, buf->tag.blockNum,
buf->tag.rnode.tblNode, buf->tag.rnode.spcNode,
buf->tag.rnode.dbNode,
buf->tag.rnode.relNode), buf->tag.rnode.relNode),
errdetail("Multiple failures --- write error may be permanent."))); errdetail("Multiple failures --- write error may be permanent.")));
} }
...@@ -1912,7 +1911,9 @@ buffer_write_error_callback(void *arg) ...@@ -1912,7 +1911,9 @@ buffer_write_error_callback(void *arg)
BufferDesc *bufHdr = (BufferDesc *) arg; BufferDesc *bufHdr = (BufferDesc *) arg;
if (bufHdr != NULL) if (bufHdr != NULL)
errcontext("writing block %u of relation %u/%u", errcontext("writing block %u of relation %u/%u/%u",
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
bufHdr->tag.rnode.tblNode, bufHdr->tag.rnode.relNode); bufHdr->tag.rnode.spcNode,
bufHdr->tag.rnode.dbNode,
bufHdr->tag.rnode.relNode);
} }
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.55 2004/05/31 20:31:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.56 2004/06/18 06:13:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -236,10 +236,10 @@ AtEOXact_LocalBuffers(bool isCommit) ...@@ -236,10 +236,10 @@ AtEOXact_LocalBuffers(bool isCommit)
if (isCommit) if (isCommit)
elog(WARNING, elog(WARNING,
"local buffer leak: [%03d] (rel=%u/%u, blockNum=%u, flags=0x%x, refcount=%u %d)", "local buffer leak: [%03d] (rel=%u/%u/%u, blockNum=%u, flags=0x%x, refcount=%u %d)",
i, i,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode, buf->tag.rnode.spcNode, buf->tag.rnode.dbNode,
buf->tag.blockNum, buf->flags, buf->tag.rnode.relNode, buf->tag.blockNum, buf->flags,
buf->refcount, LocalRefCount[i]); buf->refcount, LocalRefCount[i]);
LocalRefCount[i] = 0; LocalRefCount[i] = 0;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.31 2004/06/05 19:48:08 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.32 2004/06/18 06:13:34 tgl Exp $
* *
* *
* NOTES: * NOTES:
...@@ -658,9 +658,6 @@ FreeSpaceMapForgetRel(RelFileNode *rel) ...@@ -658,9 +658,6 @@ FreeSpaceMapForgetRel(RelFileNode *rel)
* *
* This is called during DROP DATABASE. As above, might as well reclaim * This is called during DROP DATABASE. As above, might as well reclaim
* map space sooner instead of later. * map space sooner instead of later.
*
* XXX when we implement tablespaces, target Oid will need to be tablespace
* ID not database ID.
*/ */
void void
FreeSpaceMapForgetDatabase(Oid dbid) FreeSpaceMapForgetDatabase(Oid dbid)
...@@ -672,7 +669,7 @@ FreeSpaceMapForgetDatabase(Oid dbid) ...@@ -672,7 +669,7 @@ FreeSpaceMapForgetDatabase(Oid dbid)
for (fsmrel = FreeSpaceMap->usageList; fsmrel; fsmrel = nextrel) for (fsmrel = FreeSpaceMap->usageList; fsmrel; fsmrel = nextrel)
{ {
nextrel = fsmrel->nextUsage; /* in case we delete it */ nextrel = fsmrel->nextUsage; /* in case we delete it */
if (fsmrel->key.tblNode == dbid) if (fsmrel->key.dbNode == dbid)
delete_fsm_rel(fsmrel); delete_fsm_rel(fsmrel);
} }
LWLockRelease(FreeSpaceLock); LWLockRelease(FreeSpaceLock);
...@@ -1847,8 +1844,9 @@ DumpFreeSpace(void) ...@@ -1847,8 +1844,9 @@ DumpFreeSpace(void)
for (fsmrel = FreeSpaceMap->usageList; fsmrel; fsmrel = fsmrel->nextUsage) for (fsmrel = FreeSpaceMap->usageList; fsmrel; fsmrel = fsmrel->nextUsage)
{ {
relNum++; relNum++;
fprintf(stderr, "Map %d: rel %u/%u isIndex %d avgRequest %u lastPageCount %d nextPage %d\nMap= ", fprintf(stderr, "Map %d: rel %u/%u/%u isIndex %d avgRequest %u lastPageCount %d nextPage %d\nMap= ",
relNum, fsmrel->key.tblNode, fsmrel->key.relNode, relNum,
fsmrel->key.spcNode, fsmrel->key.dbNode, fsmrel->key.relNode,
(int) fsmrel->isIndex, fsmrel->avgRequest, (int) fsmrel->isIndex, fsmrel->avgRequest,
fsmrel->lastPageCount, fsmrel->nextPage); fsmrel->lastPageCount, fsmrel->nextPage);
if (fsmrel->isIndex) if (fsmrel->isIndex)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.107 2004/06/02 17:28:18 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.108 2004/06/18 06:13:37 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -363,8 +363,9 @@ mdopen(SMgrRelation reln, bool allowNotFound) ...@@ -363,8 +363,9 @@ mdopen(SMgrRelation reln, bool allowNotFound)
return NULL; return NULL;
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not open relation %u/%u: %m", errmsg("could not open relation %u/%u/%u: %m",
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode))); reln->smgr_rnode.relNode)));
} }
} }
...@@ -765,9 +766,10 @@ mdsync(void) ...@@ -765,9 +766,10 @@ mdsync(void)
{ {
ereport(LOG, ereport(LOG,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not fsync segment %u of relation %u/%u: %m", errmsg("could not fsync segment %u of relation %u/%u/%u: %m",
entry->segno, entry->segno,
entry->rnode.tblNode, entry->rnode.spcNode,
entry->rnode.dbNode,
entry->rnode.relNode))); entry->rnode.relNode)));
return false; return false;
} }
...@@ -945,9 +947,10 @@ _mdfd_getseg(SMgrRelation reln, BlockNumber blkno, bool allowNotFound) ...@@ -945,9 +947,10 @@ _mdfd_getseg(SMgrRelation reln, BlockNumber blkno, bool allowNotFound)
return NULL; return NULL;
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not open segment %u of relation %u/%u (target block %u): %m", errmsg("could not open segment %u of relation %u/%u/%u (target block %u): %m",
nextsegno, nextsegno,
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode, reln->smgr_rnode.relNode,
blkno))); blkno)));
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.73 2004/06/02 17:28:18 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.74 2004/06/18 06:13:37 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -227,8 +227,9 @@ smgrclose(SMgrRelation reln) ...@@ -227,8 +227,9 @@ smgrclose(SMgrRelation reln)
if (! (*(smgrsw[reln->smgr_which].smgr_close)) (reln)) if (! (*(smgrsw[reln->smgr_which].smgr_close)) (reln))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not close relation %u/%u: %m", errmsg("could not close relation %u/%u/%u: %m",
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode))); reln->smgr_rnode.relNode)));
if (hash_search(SMgrRelationHash, if (hash_search(SMgrRelationHash,
...@@ -308,8 +309,9 @@ smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo) ...@@ -308,8 +309,9 @@ smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo)
if (! (*(smgrsw[reln->smgr_which].smgr_create)) (reln, isRedo)) if (! (*(smgrsw[reln->smgr_which].smgr_create)) (reln, isRedo))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not create relation %u/%u: %m", errmsg("could not create relation %u/%u/%u: %m",
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode))); reln->smgr_rnode.relNode)));
if (isRedo) if (isRedo)
...@@ -427,8 +429,9 @@ smgr_internal_unlink(RelFileNode rnode, int which, bool isTemp, bool isRedo) ...@@ -427,8 +429,9 @@ smgr_internal_unlink(RelFileNode rnode, int which, bool isTemp, bool isRedo)
if (! (*(smgrsw[which].smgr_unlink)) (rnode, isRedo)) if (! (*(smgrsw[which].smgr_unlink)) (rnode, isRedo))
ereport(WARNING, ereport(WARNING,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not unlink relation %u/%u: %m", errmsg("could not unlink relation %u/%u/%u: %m",
rnode.tblNode, rnode.spcNode,
rnode.dbNode,
rnode.relNode))); rnode.relNode)));
} }
...@@ -447,8 +450,9 @@ smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp) ...@@ -447,8 +450,9 @@ smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
isTemp)) isTemp))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not extend relation %u/%u: %m", errmsg("could not extend relation %u/%u/%u: %m",
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode), reln->smgr_rnode.relNode),
errhint("Check free disk space."))); errhint("Check free disk space.")));
} }
...@@ -467,9 +471,10 @@ smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer) ...@@ -467,9 +471,10 @@ smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer)
if (! (*(smgrsw[reln->smgr_which].smgr_read)) (reln, blocknum, buffer)) if (! (*(smgrsw[reln->smgr_which].smgr_read)) (reln, blocknum, buffer))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read block %u of relation %u/%u: %m", errmsg("could not read block %u of relation %u/%u/%u: %m",
blocknum, blocknum,
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode))); reln->smgr_rnode.relNode)));
} }
...@@ -491,9 +496,10 @@ smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp) ...@@ -491,9 +496,10 @@ smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
isTemp)) isTemp))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not write block %u of relation %u/%u: %m", errmsg("could not write block %u of relation %u/%u/%u: %m",
blocknum, blocknum,
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode))); reln->smgr_rnode.relNode)));
} }
...@@ -520,8 +526,9 @@ smgrnblocks(SMgrRelation reln) ...@@ -520,8 +526,9 @@ smgrnblocks(SMgrRelation reln)
if (nblocks == InvalidBlockNumber) if (nblocks == InvalidBlockNumber)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not count blocks of relation %u/%u: %m", errmsg("could not count blocks of relation %u/%u/%u: %m",
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode))); reln->smgr_rnode.relNode)));
return nblocks; return nblocks;
...@@ -552,8 +559,9 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp) ...@@ -552,8 +559,9 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
if (newblks == InvalidBlockNumber) if (newblks == InvalidBlockNumber)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not truncate relation %u/%u to %u blocks: %m", errmsg("could not truncate relation %u/%u/%u to %u blocks: %m",
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode, reln->smgr_rnode.relNode,
nblocks))); nblocks)));
...@@ -607,8 +615,9 @@ smgrimmedsync(SMgrRelation reln) ...@@ -607,8 +615,9 @@ smgrimmedsync(SMgrRelation reln)
if (! (*(smgrsw[reln->smgr_which].smgr_immedsync)) (reln)) if (! (*(smgrsw[reln->smgr_which].smgr_immedsync)) (reln))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not sync relation %u/%u: %m", errmsg("could not sync relation %u/%u/%u: %m",
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode))); reln->smgr_rnode.relNode)));
} }
...@@ -775,8 +784,9 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -775,8 +784,9 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
if (newblks == InvalidBlockNumber) if (newblks == InvalidBlockNumber)
ereport(WARNING, ereport(WARNING,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not truncate relation %u/%u to %u blocks: %m", errmsg("could not truncate relation %u/%u/%u to %u blocks: %m",
reln->smgr_rnode.tblNode, reln->smgr_rnode.spcNode,
reln->smgr_rnode.dbNode,
reln->smgr_rnode.relNode, reln->smgr_rnode.relNode,
xlrec->blkno))); xlrec->blkno)));
} }
...@@ -800,16 +810,17 @@ smgr_desc(char *buf, uint8 xl_info, char *rec) ...@@ -800,16 +810,17 @@ smgr_desc(char *buf, uint8 xl_info, char *rec)
{ {
xl_smgr_create *xlrec = (xl_smgr_create *) rec; xl_smgr_create *xlrec = (xl_smgr_create *) rec;
sprintf(buf + strlen(buf), "file create: %u/%u", sprintf(buf + strlen(buf), "file create: %u/%u/%u",
xlrec->rnode.tblNode, xlrec->rnode.relNode); xlrec->rnode.spcNode, xlrec->rnode.dbNode,
xlrec->rnode.relNode);
} }
else if (info == XLOG_SMGR_TRUNCATE) else if (info == XLOG_SMGR_TRUNCATE)
{ {
xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec; xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
sprintf(buf + strlen(buf), "file truncate: %u/%u to %u blocks", sprintf(buf + strlen(buf), "file truncate: %u/%u/%u to %u blocks",
xlrec->rnode.tblNode, xlrec->rnode.relNode, xlrec->rnode.spcNode, xlrec->rnode.dbNode,
xlrec->blkno); xlrec->rnode.relNode, xlrec->blkno);
} }
else else
strcat(buf, "UNKNOWN"); strcat(buf, "UNKNOWN");
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.218 2004/05/29 22:48:20 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.219 2004/06/18 06:13:38 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "commands/schemacmds.h" #include "commands/schemacmds.h"
#include "commands/sequence.h" #include "commands/sequence.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "commands/typecmds.h" #include "commands/typecmds.h"
#include "commands/user.h" #include "commands/user.h"
...@@ -258,6 +259,7 @@ check_xact_readonly(Node *parsetree) ...@@ -258,6 +259,7 @@ check_xact_readonly(Node *parsetree)
case T_CreateSchemaStmt: case T_CreateSchemaStmt:
case T_CreateSeqStmt: case T_CreateSeqStmt:
case T_CreateStmt: case T_CreateStmt:
case T_CreateTableSpaceStmt:
case T_CreateTrigStmt: case T_CreateTrigStmt:
case T_CompositeTypeStmt: case T_CompositeTypeStmt:
case T_CreateUserStmt: case T_CreateUserStmt:
...@@ -266,6 +268,7 @@ check_xact_readonly(Node *parsetree) ...@@ -266,6 +268,7 @@ check_xact_readonly(Node *parsetree)
case T_DropCastStmt: case T_DropCastStmt:
case T_DropStmt: case T_DropStmt:
case T_DropdbStmt: case T_DropdbStmt:
case T_DropTableSpaceStmt:
case T_RemoveFuncStmt: case T_RemoveFuncStmt:
case T_DropGroupStmt: case T_DropGroupStmt:
case T_DropPLangStmt: case T_DropPLangStmt:
...@@ -404,6 +407,14 @@ ProcessUtility(Node *parsetree, ...@@ -404,6 +407,14 @@ ProcessUtility(Node *parsetree,
} }
break; break;
case T_CreateTableSpaceStmt:
CreateTableSpace((CreateTableSpaceStmt *) parsetree);
break;
case T_DropTableSpaceStmt:
DropTableSpace((DropTableSpaceStmt *) parsetree);
break;
case T_DropStmt: case T_DropStmt:
{ {
DropStmt *stmt = (DropStmt *) parsetree; DropStmt *stmt = (DropStmt *) parsetree;
...@@ -636,6 +647,7 @@ ProcessUtility(Node *parsetree, ...@@ -636,6 +647,7 @@ ProcessUtility(Node *parsetree,
DefineIndex(stmt->relation, /* relation */ DefineIndex(stmt->relation, /* relation */
stmt->idxname, /* index name */ stmt->idxname, /* index name */
stmt->accessMethod, /* am name */ stmt->accessMethod, /* am name */
stmt->tableSpace,
stmt->indexParams, /* parameters */ stmt->indexParams, /* parameters */
(Expr *) stmt->whereClause, (Expr *) stmt->whereClause,
stmt->rangetable, stmt->rangetable,
...@@ -1153,6 +1165,14 @@ CreateCommandTag(Node *parsetree) ...@@ -1153,6 +1165,14 @@ CreateCommandTag(Node *parsetree)
tag = "CREATE TABLE"; tag = "CREATE TABLE";
break; break;
case T_CreateTableSpaceStmt:
tag = "CREATE TABLESPACE";
break;
case T_DropTableSpaceStmt:
tag = "DROP TABLESPACE";
break;
case T_DropStmt: case T_DropStmt:
switch (((DropStmt *) parsetree)->removeType) switch (((DropStmt *) parsetree)->removeType)
{ {
...@@ -1224,6 +1244,9 @@ CreateCommandTag(Node *parsetree) ...@@ -1224,6 +1244,9 @@ CreateCommandTag(Node *parsetree)
case OBJECT_SCHEMA: case OBJECT_SCHEMA:
tag = "ALTER SCHEMA"; tag = "ALTER SCHEMA";
break; break;
case OBJECT_TABLESPACE:
tag = "ALTER TABLESPACE";
break;
case OBJECT_TRIGGER: case OBJECT_TRIGGER:
tag = "ALTER TRIGGER"; tag = "ALTER TRIGGER";
break; break;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.105 2004/06/01 21:49:22 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.106 2004/06/18 06:13:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -539,6 +539,10 @@ acldefault(GrantObjectType objtype, AclId ownerid) ...@@ -539,6 +539,10 @@ acldefault(GrantObjectType objtype, AclId ownerid)
world_default = ACL_NO_RIGHTS; world_default = ACL_NO_RIGHTS;
owner_default = ACL_ALL_RIGHTS_NAMESPACE; owner_default = ACL_ALL_RIGHTS_NAMESPACE;
break; break;
case ACL_OBJECT_TABLESPACE:
world_default = ACL_NO_RIGHTS;
owner_default = ACL_ALL_RIGHTS_TABLESPACE;
break;
default: default:
elog(ERROR, "unrecognized objtype: %d", (int) objtype); elog(ERROR, "unrecognized objtype: %d", (int) objtype);
world_default = ACL_NO_RIGHTS; /* keep compiler quiet */ world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* back to source text * back to source text
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.172 2004/06/16 01:26:47 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.173 2004/06/18 06:13:49 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
#include "catalog/pg_trigger.h" #include "catalog/pg_trigger.h"
#include "commands/tablespace.h"
#include "executor/spi.h" #include "executor/spi.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
...@@ -767,6 +768,23 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags) ...@@ -767,6 +768,23 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
{ {
appendStringInfoChar(&buf, ')'); appendStringInfoChar(&buf, ')');
/*
* If the index is in a different tablespace from its parent,
* tell about that
*/
if (OidIsValid(idxrelrec->reltablespace) &&
idxrelrec->reltablespace != get_rel_tablespace(indrelid))
{
char *spcname = get_tablespace_name(idxrelrec->reltablespace);
if (spcname) /* just paranoia... */
{
appendStringInfo(&buf, " TABLESPACE %s",
quote_identifier(spcname));
pfree(spcname);
}
}
/* /*
* If it's a partial index, decompile and append the predicate * If it's a partial index, decompile and append the predicate
*/ */
......
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.61 2004/05/06 16:10:57 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.62 2004/06/18 06:13:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -555,14 +555,18 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple, ...@@ -555,14 +555,18 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple,
databaseId = InvalidOid; databaseId = InvalidOid;
else else
databaseId = MyDatabaseId; databaseId = MyDatabaseId;
rnode.tblNode = databaseId; /* XXX change for tablespaces */ if (classtup->reltablespace)
rnode.spcNode = classtup->reltablespace;
else
rnode.spcNode = MyDatabaseTableSpace;
rnode.dbNode = databaseId;
rnode.relNode = classtup->relfilenode; rnode.relNode = classtup->relfilenode;
/* /*
* Note: during a pg_class row update that assigns a new relfilenode * Note: during a pg_class row update that assigns a new relfilenode
* value, we will be called on both the old and new tuples, and thus * or reltablespace value, we will be called on both the old and new
* will broadcast invalidation messages showing both the old and new * tuples, and thus will broadcast invalidation messages showing both
* relfilenode values. This ensures that other backends will close * the old and new RelFileNode values. This ensures that other
* smgr references to the old relfilenode file. * backends will close smgr references to the old file.
*/ */
} }
else if (tupleRelId == RelOid_pg_attribute) else if (tupleRelId == RelOid_pg_attribute)
...@@ -580,7 +584,8 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple, ...@@ -580,7 +584,8 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple,
*/ */
databaseId = MyDatabaseId; databaseId = MyDatabaseId;
/* We assume no smgr cache flush is needed, either */ /* We assume no smgr cache flush is needed, either */
rnode.tblNode = InvalidOid; rnode.spcNode = InvalidOid;
rnode.dbNode = InvalidOid;
rnode.relNode = InvalidOid; rnode.relNode = InvalidOid;
} }
else else
...@@ -760,7 +765,11 @@ CacheInvalidateRelcacheByTuple(HeapTuple classTuple) ...@@ -760,7 +765,11 @@ CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
databaseId = InvalidOid; databaseId = InvalidOid;
else else
databaseId = MyDatabaseId; databaseId = MyDatabaseId;
rnode.tblNode = databaseId; /* XXX change for tablespaces */ if (classtup->reltablespace)
rnode.spcNode = classtup->reltablespace;
else
rnode.spcNode = MyDatabaseTableSpace;
rnode.dbNode = databaseId;
rnode.relNode = classtup->relfilenode; rnode.relNode = classtup->relfilenode;
RegisterRelcacheInvalidation(databaseId, relationId, rnode); RegisterRelcacheInvalidation(databaseId, relationId, rnode);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.113 2004/06/06 00:41:27 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.114 2004/06/18 06:13:52 tgl Exp $
* *
* NOTES * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
...@@ -985,6 +985,34 @@ get_rel_namespace(Oid relid) ...@@ -985,6 +985,34 @@ get_rel_namespace(Oid relid)
return InvalidOid; return InvalidOid;
} }
/*
* get_rel_tablespace
* Returns the pg_tablespace OID associated with a given relation.
*
* Note: failure return is InvalidOid, which cannot be distinguished from
* "default tablespace for this database", but that seems OK.
*/
Oid
get_rel_tablespace(Oid relid)
{
HeapTuple tp;
tp = SearchSysCache(RELOID,
ObjectIdGetDatum(relid),
0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
Oid result;
result = reltup->reltablespace;
ReleaseSysCache(tp);
return result;
}
else
return InvalidOid;
}
/* /*
* get_rel_type_id * get_rel_type_id
* *
...@@ -1980,6 +2008,34 @@ get_namespace_name(Oid nspid) ...@@ -1980,6 +2008,34 @@ get_namespace_name(Oid nspid)
return NULL; return NULL;
} }
/*
* get_namespace_tablespace
* Returns the default tablespace of a given namespace
*
* Note: failure return is InvalidOid, which cannot be distinguished from
* "default tablespace for this database", but that seems OK.
*/
Oid
get_namespace_tablespace(Oid nspid)
{
HeapTuple tp;
tp = SearchSysCache(NAMESPACEOID,
ObjectIdGetDatum(nspid),
0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
Oid result;
result = nsptup->nsptablespace;
ReleaseSysCache(tp);
return result;
}
else
return InvalidOid;
}
/* ---------- PG_SHADOW CACHE ---------- */ /* ---------- PG_SHADOW CACHE ---------- */
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.204 2004/05/30 23:40:37 neilc Exp $ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.205 2004/06/18 06:13:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -260,6 +260,7 @@ static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, ...@@ -260,6 +260,7 @@ static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
Relation relation); Relation relation);
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo, static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
Relation oldrelation); Relation oldrelation);
static void RelationInitPhysicalAddr(Relation relation);
static void AttrDefaultFetch(Relation relation); static void AttrDefaultFetch(Relation relation);
static void CheckConstraintFetch(Relation relation); static void CheckConstraintFetch(Relation relation);
static List *insert_ordered_oid(List *list, Oid datum); static List *insert_ordered_oid(List *list, Oid datum);
...@@ -873,11 +874,10 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo, ...@@ -873,11 +874,10 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
*/ */
RelationInitLockInfo(relation); /* see lmgr.c */ RelationInitLockInfo(relation); /* see lmgr.c */
if (relation->rd_rel->relisshared) /*
relation->rd_node.tblNode = InvalidOid; * initialize physical addressing information for the relation
else */
relation->rd_node.tblNode = MyDatabaseId; RelationInitPhysicalAddr(relation);
relation->rd_node.relNode = relation->rd_rel->relfilenode;
/* make sure relation is marked as having no open file yet */ /* make sure relation is marked as having no open file yet */
relation->rd_smgr = NULL; relation->rd_smgr = NULL;
...@@ -892,6 +892,23 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo, ...@@ -892,6 +892,23 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
return relation; return relation;
} }
/*
* Initialize the physical addressing info (RelFileNode) for a relcache entry
*/
static void
RelationInitPhysicalAddr(Relation relation)
{
if (relation->rd_rel->reltablespace)
relation->rd_node.spcNode = relation->rd_rel->reltablespace;
else
relation->rd_node.spcNode = MyDatabaseTableSpace;
if (relation->rd_rel->relisshared)
relation->rd_node.dbNode = InvalidOid;
else
relation->rd_node.dbNode = MyDatabaseId;
relation->rd_node.relNode = relation->rd_rel->relfilenode;
}
/* /*
* Initialize index-access-method support data for an index relation * Initialize index-access-method support data for an index relation
*/ */
...@@ -1343,18 +1360,17 @@ formrdesc(const char *relationName, ...@@ -1343,18 +1360,17 @@ formrdesc(const char *relationName,
* initialize relation id from info in att array (my, this is ugly) * initialize relation id from info in att array (my, this is ugly)
*/ */
RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid; RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid;
relation->rd_rel->relfilenode = RelationGetRelid(relation);
/* /*
* initialize the relation's lock manager and RelFileNode information * initialize the relation lock manager information
*/ */
RelationInitLockInfo(relation); /* see lmgr.c */ RelationInitLockInfo(relation); /* see lmgr.c */
if (relation->rd_rel->relisshared) /*
relation->rd_node.tblNode = InvalidOid; * initialize physical addressing information for the relation
else */
relation->rd_node.tblNode = MyDatabaseId; RelationInitPhysicalAddr(relation);
relation->rd_node.relNode =
relation->rd_rel->relfilenode = RelationGetRelid(relation);
/* /*
* initialize the rel-has-index flag, using hardwired knowledge * initialize the rel-has-index flag, using hardwired knowledge
...@@ -1570,7 +1586,8 @@ RelationReloadClassinfo(Relation relation) ...@@ -1570,7 +1586,8 @@ RelationReloadClassinfo(Relation relation)
relation->rd_id); relation->rd_id);
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple); relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE); memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
relation->rd_node.relNode = relp->relfilenode; /* Now we can recalculate physical address */
RelationInitPhysicalAddr(relation);
heap_freetuple(pg_class_tuple); heap_freetuple(pg_class_tuple);
relation->rd_targblock = InvalidBlockNumber; relation->rd_targblock = InvalidBlockNumber;
/* Okay, now it's valid again */ /* Okay, now it's valid again */
...@@ -2040,8 +2057,9 @@ Relation ...@@ -2040,8 +2057,9 @@ Relation
RelationBuildLocalRelation(const char *relname, RelationBuildLocalRelation(const char *relname,
Oid relnamespace, Oid relnamespace,
TupleDesc tupDesc, TupleDesc tupDesc,
Oid relid, Oid dbid, Oid relid,
RelFileNode rnode, Oid reltablespace,
bool shared_relation,
bool nailit) bool nailit)
{ {
Relation rel; Relation rel;
...@@ -2125,20 +2143,23 @@ RelationBuildLocalRelation(const char *relname, ...@@ -2125,20 +2143,23 @@ RelationBuildLocalRelation(const char *relname,
/* /*
* Insert relation physical and logical identifiers (OIDs) into the * Insert relation physical and logical identifiers (OIDs) into the
* right places. * right places. Note that the physical ID (relfilenode) is initially
* the same as the logical ID (OID).
*/ */
rel->rd_rel->relisshared = (dbid == InvalidOid); rel->rd_rel->relisshared = shared_relation;
RelationGetRelid(rel) = relid; RelationGetRelid(rel) = relid;
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
rel->rd_att->attrs[i]->attrelid = relid; rel->rd_att->attrs[i]->attrelid = relid;
rel->rd_node = rnode; rel->rd_rel->relfilenode = relid;
rel->rd_rel->relfilenode = rnode.relNode; rel->rd_rel->reltablespace = reltablespace;
RelationInitLockInfo(rel); /* see lmgr.c */ RelationInitLockInfo(rel); /* see lmgr.c */
RelationInitPhysicalAddr(rel);
/* /*
* Okay to insert into the relcache hash tables. * Okay to insert into the relcache hash tables.
*/ */
...@@ -3053,16 +3074,12 @@ load_relcache_init_file(void) ...@@ -3053,16 +3074,12 @@ load_relcache_init_file(void)
MemSet(&rel->pgstat_info, 0, sizeof(rel->pgstat_info)); MemSet(&rel->pgstat_info, 0, sizeof(rel->pgstat_info));
/* /*
* Make sure database ID is correct. This is needed in case the * Recompute lock and physical addressing info. This is needed in
* pg_internal.init file was copied from some other database by * case the pg_internal.init file was copied from some other database
* CREATE DATABASE. * by CREATE DATABASE.
*/ */
if (rel->rd_rel->relisshared)
rel->rd_node.tblNode = InvalidOid;
else
rel->rd_node.tblNode = MyDatabaseId;
RelationInitLockInfo(rel); RelationInitLockInfo(rel);
RelationInitPhysicalAddr(rel);
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.90 2004/05/30 17:58:12 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.91 2004/06/18 06:13:54 tgl Exp $
* *
* NOTES * NOTES
* Globals used all over the place should be declared here and not * Globals used all over the place should be declared here and not
...@@ -58,6 +58,8 @@ BackendId MyBackendId = InvalidBackendId; ...@@ -58,6 +58,8 @@ BackendId MyBackendId = InvalidBackendId;
char *DatabasePath = NULL; char *DatabasePath = NULL;
Oid MyDatabaseId = InvalidOid; Oid MyDatabaseId = InvalidOid;
Oid MyDatabaseTableSpace = InvalidOid;
pid_t PostmasterPid = 0; pid_t PostmasterPid = 0;
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.126 2004/05/30 23:40:38 neilc Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.127 2004/06/18 06:13:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -157,7 +157,6 @@ void ...@@ -157,7 +157,6 @@ void
SetDataDir(const char *dir) SetDataDir(const char *dir)
{ {
char *new; char *new;
int newlen;
AssertArg(dir); AssertArg(dir);
...@@ -212,13 +211,7 @@ SetDataDir(const char *dir) ...@@ -212,13 +211,7 @@ SetDataDir(const char *dir)
* Strip any trailing slash. Not strictly necessary, but avoids * Strip any trailing slash. Not strictly necessary, but avoids
* generating funny-looking paths to individual files. * generating funny-looking paths to individual files.
*/ */
newlen = strlen(new); canonicalize_path(new);
if (newlen > 1 && (new[newlen - 1] == '/'
#ifdef WIN32
|| new[newlen - 1] == '\\'
#endif
))
new[newlen - 1] = '\0';
if (DataDir) if (DataDir)
free(DataDir); free(DataDir);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.133 2004/05/29 22:48:21 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.134 2004/06/18 06:13:54 tgl Exp $
* *
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"
#include "miscadmin.h" #include "miscadmin.h"
...@@ -239,12 +240,12 @@ InitPostgres(const char *dbname, const char *username) ...@@ -239,12 +240,12 @@ InitPostgres(const char *dbname, const char *username)
if (bootstrap) if (bootstrap)
{ {
MyDatabaseId = TemplateDbOid; MyDatabaseId = TemplateDbOid;
SetDatabasePath(GetDatabasePath(MyDatabaseId)); MyDatabaseTableSpace = DEFAULTTABLESPACE_OID;
SetDatabasePath(GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace));
} }
else else
{ {
char *fullpath, char *fullpath;
datpath[MAXPGPATH];
/* /*
* Formerly we validated DataDir here, but now that's done * Formerly we validated DataDir here, but now that's done
...@@ -252,11 +253,11 @@ InitPostgres(const char *dbname, const char *username) ...@@ -252,11 +253,11 @@ InitPostgres(const char *dbname, const char *username)
*/ */
/* /*
* Find oid and path of the database we're about to open. Since * Find oid and tablespace of the database we're about to open.
* we're not yet up and running we have to use the hackish * Since we're not yet up and running we have to use the hackish
* GetRawDatabaseInfo. * GetRawDatabaseInfo.
*/ */
GetRawDatabaseInfo(dbname, &MyDatabaseId, datpath); GetRawDatabaseInfo(dbname, &MyDatabaseId, &MyDatabaseTableSpace);
if (!OidIsValid(MyDatabaseId)) if (!OidIsValid(MyDatabaseId))
ereport(FATAL, ereport(FATAL,
...@@ -264,7 +265,7 @@ InitPostgres(const char *dbname, const char *username) ...@@ -264,7 +265,7 @@ InitPostgres(const char *dbname, const char *username)
errmsg("database \"%s\" does not exist", errmsg("database \"%s\" does not exist",
dbname))); dbname)));
fullpath = GetDatabasePath(MyDatabaseId); fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
/* Verify the database path */ /* Verify the database path */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/database.c,v 1.60 2004/01/22 20:57:39 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/database.c,v 1.61 2004/06/18 06:13:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "catalog/pg_tablespace.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/syscache.h" #include "utils/syscache.h"
...@@ -29,12 +30,13 @@ static bool PhonyHeapTupleSatisfiesNow(HeapTupleHeader tuple); ...@@ -29,12 +30,13 @@ static bool PhonyHeapTupleSatisfiesNow(HeapTupleHeader tuple);
/* -------------------------------- /* --------------------------------
* GetRawDatabaseInfo() -- Find the OID and path of the database. * GetRawDatabaseInfo() -- Find the OID and tablespace of the database.
* *
* The database's oid forms half of the unique key for the system * We need both the OID and the default tablespace in order to find
* caches and lock tables. We therefore want it initialized before * the database's system catalogs. Moreover the database's OID forms
* we open any relations, since opening relations puts things in the * half of the unique key for the system caches and lock tables, so
* cache. To get around this problem, this code opens and scans the * we must have it before we can use any of the cache mechanisms.
* To get around these problems, this code opens and scans the
* pg_database relation by hand. * pg_database relation by hand.
* *
* This code knows way more than it should about the layout of * This code knows way more than it should about the layout of
...@@ -43,19 +45,21 @@ static bool PhonyHeapTupleSatisfiesNow(HeapTupleHeader tuple); ...@@ -43,19 +45,21 @@ static bool PhonyHeapTupleSatisfiesNow(HeapTupleHeader tuple);
* -------------------------------- * --------------------------------
*/ */
void void
GetRawDatabaseInfo(const char *name, Oid *db_id, char *path) GetRawDatabaseInfo(const char *name, Oid *db_id, Oid *db_tablespace)
{ {
int dbfd; int dbfd;
int nbytes; int nbytes;
int pathlen;
HeapTupleData tup; HeapTupleData tup;
Form_pg_database tup_db;
Page pg; Page pg;
char *dbfname; char *dbfname;
Form_pg_database tup_db;
RelFileNode rnode; RelFileNode rnode;
rnode.tblNode = 0; /* hard-wired path to pg_database */
rnode.spcNode = GLOBALTABLESPACE_OID;
rnode.dbNode = 0;
rnode.relNode = RelOid_pg_database; rnode.relNode = RelOid_pg_database;
dbfname = relpath(rnode); dbfname = relpath(rnode);
if ((dbfd = open(dbfname, O_RDONLY | PG_BINARY, 0)) < 0) if ((dbfd = open(dbfname, O_RDONLY | PG_BINARY, 0)) < 0)
...@@ -121,7 +125,7 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path) ...@@ -121,7 +125,7 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
* committed and dead tuples to be marked with correct states. * committed and dead tuples to be marked with correct states.
* *
* XXX wouldn't it be better to let new backends read the * XXX wouldn't it be better to let new backends read the
* database OID from a flat file, handled the same way we * database info from a flat file, handled the same way we
* handle the password relation? * handle the password relation?
*/ */
if (!PhonyHeapTupleSatisfiesNow(tup.t_data)) if (!PhonyHeapTupleSatisfiesNow(tup.t_data))
...@@ -134,15 +138,9 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path) ...@@ -134,15 +138,9 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
if (strcmp(name, NameStr(tup_db->datname)) == 0) if (strcmp(name, NameStr(tup_db->datname)) == 0)
{ {
/* Found it; extract the OID and the database path. */ /* Found it; extract the db's OID and tablespace. */
*db_id = HeapTupleGetOid(&tup); *db_id = HeapTupleGetOid(&tup);
pathlen = VARSIZE(&(tup_db->datpath)) - VARHDRSZ; *db_tablespace = tup_db->dattablespace;
if (pathlen < 0)
pathlen = 0; /* pure paranoia */
if (pathlen >= MAXPGPATH)
pathlen = MAXPGPATH - 1; /* more paranoia */
strncpy(path, VARDATA(&(tup_db->datpath)), pathlen);
path[pathlen] = '\0';
goto done; goto done;
} }
} }
...@@ -150,7 +148,7 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path) ...@@ -150,7 +148,7 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
/* failed to find it... */ /* failed to find it... */
*db_id = InvalidOid; *db_id = InvalidOid;
*path = '\0'; *db_tablespace = InvalidOid;
done: done:
close(dbfd); close(dbfd);
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* Portions taken from FreeBSD. * Portions taken from FreeBSD.
* *
* $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.37 2004/06/10 22:26:20 momjian Exp $ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.38 2004/06/18 06:13:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1785,7 +1785,7 @@ main(int argc, char *argv[]) ...@@ -1785,7 +1785,7 @@ main(int argc, char *argv[])
char *pgdenv; /* PGDATA value got from sent to char *pgdenv; /* PGDATA value got from sent to
* environment */ * environment */
char *subdirs[] = char *subdirs[] =
{"global", "pg_xlog", "pg_clog", "base", "base/1"}; {"global", "pg_xlog", "pg_clog", "base", "base/1", "pg_tablespaces"};
progname = get_progname(argv[0]); progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], "initdb"); set_pglocale_pgservice(argv[0], "initdb");
...@@ -2141,7 +2141,7 @@ main(int argc, char *argv[]) ...@@ -2141,7 +2141,7 @@ main(int argc, char *argv[])
/* Bootstrap template1 */ /* Bootstrap template1 */
bootstrap_template1(short_version); bootstrap_template1(short_version);
/* Make the per-database PGVERSION for template1 only after init'ing it */ /* Make the per-database PG_VERSION for template1 only after init'ing it */
set_short_version(short_version, "base/1"); set_short_version(short_version, "base/1");
/* Create the stuff we don't need to use bootstrap mode for */ /* Create the stuff we don't need to use bootstrap mode for */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.12 2004/03/23 22:06:08 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.13 2004/06/18 06:14:00 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -586,6 +586,8 @@ parseAclItem(const char *item, const char *type, const char *name, ...@@ -586,6 +586,8 @@ parseAclItem(const char *item, const char *type, const char *name,
CONVERT_PRIV('C', "CREATE"); CONVERT_PRIV('C', "CREATE");
CONVERT_PRIV('T', "TEMPORARY"); CONVERT_PRIV('T', "TEMPORARY");
} }
else if (strcmp(type, "TABLESPACE") == 0)
CONVERT_PRIV('C', "CREATE");
else else
abort(); abort();
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.108 2004/03/03 21:28:55 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.109 2004/06/18 06:14:00 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -98,6 +98,7 @@ typedef struct _namespaceInfo ...@@ -98,6 +98,7 @@ typedef struct _namespaceInfo
DumpableObject dobj; DumpableObject dobj;
char *usename; /* name of owner, or empty string */ char *usename; /* name of owner, or empty string */
char *nspacl; char *nspacl;
char *nsptablespace; /* default tablespace */
bool dump; /* true if need to dump definition */ bool dump; /* true if need to dump definition */
} NamespaceInfo; } NamespaceInfo;
...@@ -168,6 +169,7 @@ typedef struct _tableInfo ...@@ -168,6 +169,7 @@ typedef struct _tableInfo
char *usename; /* name of owner, or empty string */ char *usename; /* name of owner, or empty string */
char *relacl; char *relacl;
char relkind; char relkind;
char *reltablespace; /* relation tablespace */
bool hasindex; /* does it have any indexes? */ bool hasindex; /* does it have any indexes? */
bool hasrules; /* does it have any rules? */ bool hasrules; /* does it have any rules? */
bool hasoids; /* does it have OIDs? */ bool hasoids; /* does it have OIDs? */
......
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * Copyright (c) 2000-2003, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.116 2004/05/07 00:24:58 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.117 2004/06/18 06:14:04 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "command.h" #include "command.h"
...@@ -301,6 +301,9 @@ exec_command(const char *cmd, ...@@ -301,6 +301,9 @@ exec_command(const char *cmd,
case 'a': case 'a':
success = describeAggregates(pattern, show_verbose); success = describeAggregates(pattern, show_verbose);
break; break;
case 'b':
success = describeTablespaces(pattern);
break;
case 'c': case 'c':
success = listConversions(pattern); success = listConversions(pattern);
break; break;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * Copyright (c) 2000-2003, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.98 2004/05/07 00:24:58 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.99 2004/06/18 06:14:04 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "describe.h" #include "describe.h"
...@@ -99,6 +99,45 @@ describeAggregates(const char *pattern, bool verbose) ...@@ -99,6 +99,45 @@ describeAggregates(const char *pattern, bool verbose)
return true; return true;
} }
/* \db
* Takes an optional regexp to select particular tablespaces
*/
bool
describeTablespaces(const char *pattern)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf,
"SELECT spcname AS \"%s\",\n"
" pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n"
" spclocation AS \"%s\"\n"
"FROM pg_catalog.pg_tablespace\n",
_("Name"), _("Owner"), _("Location"));
processNamePattern(&buf, pattern, false, false,
NULL, "spcname", NULL,
NULL);
appendPQExpBuffer(&buf, "ORDER BY 1;");
res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
myopt.nullPrint = NULL;
myopt.title = _("List of tablespaces");
printQuery(res, &myopt, pset.queryFout);
PQclear(res);
return true;
}
/* \df /* \df
* Takes an optional regexp to select particular functions * Takes an optional regexp to select particular functions
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * Copyright (c) 2000-2003, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.23 2003/12/01 22:21:54 momjian Exp $ * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.24 2004/06/18 06:14:04 tgl Exp $
*/ */
#ifndef DESCRIBE_H #ifndef DESCRIBE_H
#define DESCRIBE_H #define DESCRIBE_H
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
/* \da */ /* \da */
bool describeAggregates(const char *pattern, bool verbose); bool describeAggregates(const char *pattern, bool verbose);
/* \db */
bool describeTablespaces(const char *pattern);
/* \df */ /* \df */
bool describeFunctions(const char *pattern, bool verbose); bool describeFunctions(const char *pattern, bool verbose);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * Copyright (c) 2000-2003, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.87 2004/05/07 00:24:58 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.88 2004/06/18 06:14:04 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "common.h" #include "common.h"
...@@ -211,6 +211,7 @@ slashUsage(unsigned short int pager) ...@@ -211,6 +211,7 @@ slashUsage(unsigned short int pager)
fprintf(output, _(" \\d{t|i|s|v|S} [PATTERN] (add \"+\" for more detail)\n" fprintf(output, _(" \\d{t|i|s|v|S} [PATTERN] (add \"+\" for more detail)\n"
" list tables/indexes/sequences/views/system tables\n")); " list tables/indexes/sequences/views/system tables\n"));
fprintf(output, _(" \\da [PATTERN] list aggregate functions\n")); fprintf(output, _(" \\da [PATTERN] list aggregate functions\n"));
fprintf(output, _(" \\db [PATTERN] list tablespaces\n"));
fprintf(output, _(" \\dc [PATTERN] list conversions\n")); fprintf(output, _(" \\dc [PATTERN] list conversions\n"));
fprintf(output, _(" \\dC list casts\n")); fprintf(output, _(" \\dC list casts\n"));
fprintf(output, _(" \\dd [PATTERN] show comment for object\n")); fprintf(output, _(" \\dd [PATTERN] show comment for object\n"));
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catalog.h,v 1.27 2003/11/29 22:40:58 pgsql Exp $ * $PostgreSQL: pgsql/src/include/catalog/catalog.h,v 1.28 2004/06/18 06:14:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
extern char *relpath(RelFileNode rnode); extern char *relpath(RelFileNode rnode);
extern char *GetDatabasePath(Oid tblNode); extern char *GetDatabasePath(Oid dbNode, Oid spcNode);
extern bool IsSystemRelation(Relation relation); extern bool IsSystemRelation(Relation relation);
extern bool IsToastRelation(Relation relation); extern bool IsToastRelation(Relation relation);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catname.h,v 1.31 2003/11/29 22:40:58 pgsql Exp $ * $PostgreSQL: pgsql/src/include/catalog/catname.h,v 1.32 2004/06/18 06:14:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define RewriteRelationName "pg_rewrite" #define RewriteRelationName "pg_rewrite"
#define ShadowRelationName "pg_shadow" #define ShadowRelationName "pg_shadow"
#define StatisticRelationName "pg_statistic" #define StatisticRelationName "pg_statistic"
#define TableSpaceRelationName "pg_tablespace"
#define TypeRelationName "pg_type" #define TypeRelationName "pg_type"
#define VersionRelationName "pg_version" #define VersionRelationName "pg_version"
#define AttrDefaultRelationName "pg_attrdef" #define AttrDefaultRelationName "pg_attrdef"
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.236 2004/06/16 01:26:49 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.237 2004/06/18 06:14:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200406151 #define CATALOG_VERSION_NO 200406171
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -78,3 +78,6 @@ test: limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion ...@@ -78,3 +78,6 @@ test: limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion
# run stats by itself because its delay may be insufficient under heavy load # run stats by itself because its delay may be insufficient under heavy load
test: stats test: stats
# run tablespace by itself
test: tablespace
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment