Add more information about schemas. Combines some previously existing

material into the new location.
This commit is contained in:
Peter Eisentraut 2002-09-12 22:05:36 +00:00
parent feb202193d
commit 6d77f6e5fb
4 changed files with 614 additions and 308 deletions

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ddl.sgml,v 1.3 2002/09/05 21:32:23 petere Exp $ -->
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ddl.sgml,v 1.4 2002/09/12 22:05:35 petere Exp $ -->
<chapter id="ddl">
<title>Data Definition</title>
@ -142,6 +142,120 @@ DROP TABLE products;
</para>
</sect1>
<sect1 id="ddl-system-columns">
<title>System Columns</title>
<para>
Every table has several <firstterm>system columns</> that are
implicitly defined by the system. Therefore, these names cannot be
used as names of user-defined columns. (Note that these
restrictions are separate from whether the name is a key word or
not; quoting a name will not allow you to escape these
restrictions.) You do not really need to be concerned about these
columns, just know they exist.
</para>
<indexterm>
<primary>columns</primary>
<secondary>system columns</secondary>
</indexterm>
<variablelist>
<varlistentry>
<term><structfield>oid</></term>
<listitem>
<para>
<indexterm>
<primary>OID</primary>
</indexterm>
The object identifier (object ID) of a row. This is a serial
number that is automatically added by
<productname>PostgreSQL</productname> to all table rows (unless
the table was created <literal>WITHOUT OIDS</literal>, in which
case this column is not present). This column is of type
<literal>oid</literal> (same name as the column); see <xref
linkend="datatype-oid"> for more information about the type.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>tableoid</></term>
<listitem>
<para>
The OID of the table containing this row. This attribute is
particularly handy for queries that select from inheritance
hierarchies, since without it, it's difficult to tell which
individual table a row came from. The
<structfield>tableoid</structfield> can be joined against the
<structfield>oid</structfield> column of
<classname>pg_class</classname> to obtain the table name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>xmin</></term>
<listitem>
<para>
The identity (transaction ID) of the inserting transaction for
this tuple. (Note: In this context, a tuple is an individual
state of a row; each update of a row creates a new tuple for the
same logical row.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>cmin</></term>
<listitem>
<para>
The command identifier (starting at zero) within the inserting
transaction.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>xmax</></term>
<listitem>
<para>
The identity (transaction ID) of the deleting transaction, or
zero for an undeleted tuple. It is possible for this field to
be nonzero in a visible tuple: that usually indicates that the
deleting transaction hasn't committed yet, or that an attempted
deletion was rolled back.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>cmax</></term>
<listitem>
<para>
The command identifier within the deleting transaction, or zero.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>ctid</></term>
<listitem>
<para>
The physical location of the tuple within its table. Note that
although the <structfield>ctid</structfield> can be used to
locate the tuple very quickly, a row's
<structfield>ctid</structfield> will change each time it is
updated or moved by <command>VACUUM FULL</>. Therefore
<structfield>ctid</structfield> is useless as a long-term row
identifier. The OID, or even better a user-defined serial
number, should be used to identify logical rows.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect1>
<sect1>
<title>Default Values</title>
@ -1016,11 +1130,502 @@ ALTER TABLE products RENAME TO items;
</para>
</sect2>
</sect1>
<sect1 id="ddl-priv">
<title>Privileges</title>
<para>
When you create a database object, you become its owner. By
default, only the owner of an object can do anything with the
object. In order to allow other users to use it,
<firstterm>privileges</firstterm> must be granted. (There are also
users that have the superuser privilege. Those users can always
access any object.)
</para>
<note>
<para>
To change the owner of a table, index, sequence, or view, use the
<command>ALTER TABLE</command> command.
</para>
</note>
<para>
There are several different privileges: <literal>SELECT</>,
<literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
<literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>,
<literal>CREATE</>, <literal>TEMPORARY</>, <literal>EXECUTE</>,
<literal>USAGE</>, and <literal>ALL PRIVILEGES</>. For complete
information on the different types of privileges supported by
<productname>PostgreSQL</productname>, refer to the
<command>GRANT</command> reference page. The following sections
and chapters will also show you how those privileges are used.
</para>
<para>
The right to modify or destroy an object is always the privilege of
the owner only.
</para>
<para>
To assign privileges, the <command>GRANT</command> command is
used. So, if <literal>joe</literal> is an existing user, and
<literal>accounts</literal> is an existing table, the privilege to
update the table can be granted with
<programlisting>
GRANT UPDATE ON accounts TO joe;
</programlisting>
The user executing this command must be the owner of the table. To
grant a privilege to a group, use
<programlisting>
GRANT SELECT ON accounts TO GROUP staff;
</programlisting>
The special <quote>user</quote> name <literal>PUBLIC</literal> can
be used to grant a privilege to every user on the system. Writing
<literal>ALL</literal> in place of a specific privilege specifies that all
privileges will be granted.
</para>
<para>
To revoke a privilege, use the fittingly named
<command>REVOKE</command> command:
<programlisting>
REVOKE ALL ON accounts FROM PUBLIC;
</programlisting>
The special privileges of the table owner (i.e., the right to do
<command>DROP</>, <command>GRANT</>, <command>REVOKE</>, etc)
are always implicit in being the owner,
and cannot be granted or revoked. But the table owner can choose
to revoke his own ordinary privileges, for example to make a
table read-only for himself as well as others.
</para>
</sect1>
<sect1 id="ddl-schemas">
<title>Schemas</title>
<comment>to be filled in</comment>
<indexterm>
<primary>schemas</primary>
</indexterm>
<indexterm>
<primary>namespaces</primary>
</indexterm>
<para>
A <productname>PostgreSQL</productname> database cluster (installation)
contains one or more named databases. Users and groups of users are
shared across the entire cluster, but no other data is shared across
databases. Any given client connection to the server can access
only the data in a single database, the one specified in the connection
request.
</para>
<note>
<para>
Users of a cluster do not necessarily have the privilege to access every
database in the cluster. Sharing of user names means that there
cannot be different users named, say, <literal>joe</> in two databases
in the same cluster; but the system can be configured to allow
<literal>joe</> access to only some of the databases.
</para>
</note>
<para>
A database contains one or more named <firstterm>schemas</>, which
in turn contain tables. Schemas also contain other kinds of named
objects, including data types, functions, and operators. The same
object name can be used in different schemas without conflict; for
example, both <literal>schema1</> and <literal>myschema</> may
contain tables named <literal>mytable</>. Unlike databases,
schemas are not rigidly separated: a user may access objects in any
of the schemas in the database he is connected to, if he has
privileges to do so.
</para>
<para>
There are several reasons why one might want to use schemas:
<itemizedlist>
<listitem>
<para>
To allow many users to use one database without interfering with
each other.
</para>
</listitem>
<listitem>
<para>
To organize database objects into logical groups to make them
more manageable.
</para>
</listitem>
<listitem>
<para>
Third-party applications can be put into separate schemas so
they cannot collide with the names of other objects.
</para>
</listitem>
</itemizedlist>
Schemas are analogous to directories at the operating system level,
but schemas cannot be nested.
</para>
<sect2 id="ddl-schemas-create">
<title>Creating a Schema</title>
<para>
To create a separate schema, use the command <literal>CREATE
SCHEMA</literal>. Give the schema a name of your choice. For
example:
<programlisting>
CREATE SCHEMA myschema;
</programlisting>
</para>
<indexterm>
<primary>qualified names</primary>
</indexterm>
<indexterm>
<primary>names</primary>
<secondary>qualified</secondary>
</indexterm>
<para>
To create or access objects in a schema, write a
<firstterm>qualified name</> consisting of the schema name and
table name separated by a dot:
<synopsis>
<replaceable>schema</><literal>.</><replaceable>table</>
</synopsis>
Actually, the even more general syntax
<synopsis>
<replaceable>database</><literal>.</><replaceable>schema</><literal>.</><replaceable>table</>
</synopsis>
can be used too, but at present this is just for pro-forma compliance
with the SQL standard; if you write a database name it must be the
same as the database you are connected to.
</para>
<para>
So to create a table in the new schema, use
<programlisting>
CREATE TABLE myschema.mytable (
...
);
</programlisting>
This works anywhere a table name is expected, including the table
modification commands and the data access commands discussed in
the following chapters.
</para>
<para>
To drop a schema if it's empty (all objects in it have been
dropped), use
<programlisting>
DROP SCHEMA myschema;
</programlisting>
To drop a schema including all contained objects, use
<programlisting>
DROP SCHEMA myschema CASCADE;
</programlisting>
See <xref linkend="ddl-depend"> for a description of the general
mechanism behind this.
</para>
<para>
Often you will want to create a schema owned by someone else
(since this is one of the ways to restrict the activities of your
users to well-defined namespaces). The syntax for that is:
<programlisting>
CREATE SCHEMA <replaceable>schemaname</replaceable> AUTHORIZATON <replaceable>username</replaceable>;
</programlisting>
You can even omit the schema name, in which case the schema name
will be the same as the user name. See <xref
linkend="ddl-schemas-patterns"> for how this can be useful.
</para>
<para>
Schema names beginning with <literal>pg_</> are reserved for
system purposes and may not be created by users.
</para>
</sect2>
<sect2 id="ddl-schemas-public">
<title>The Public Schema</title>
<para>
In the previous sections we created tables without specifying any
schema names. Those tables (and other objects) are automatically
put into a schema named <quote>public</quote>. Every new database
contains such a schema. Thus, the following are equivalent:
<programlisting>
CREATE TABLE products ( ... );
</programlisting>
and
<programlisting>
CREATE TABLE public.products ( ... );
</programlisting>
</para>
</sect2>
<sect2 id="ddl-schemas-path">
<title>The Schema Search Path</title>
<indexterm>
<primary>search path</primary>
</indexterm>
<indexterm>
<primary>unqualified names</primary>
</indexterm>
<indexterm>
<primary>names</primary>
<secondary>unqualified</secondary>
</indexterm>
<para>
Qualified names are tedious to write, and it's often best not to
wire a particular schema name into applications anyway. Therefore
tables are often referred to by <firstterm>unqualified names</>,
which consist of just the table name. The system determines which table
is meant by following a <firstterm>search path</>, which is a list
of schemas to look in. The first matching table in the search path
is taken to be the one wanted. If there is no match in the search
path, an error is reported, even if matching table names exist
in other schemas in the database.
</para>
<para>
The first schema named in the search path is called the current schema.
Aside from being the first schema searched, it is also the schema in
which new tables will be created if the <command>CREATE TABLE</>
command does not specify a schema name.
</para>
<para>
To show the current search path, use the following command:
<programlisting>
SHOW search_path;
</programlisting>
In the default setup this returns:
<screen>
search_path
--------------
$user,public
</screen>
The first element specifies that a schema with the same name as
the current user is to be searched. Since no such schema exists
yet, this entry is ignored. The second element refers to the
public schema that we have seen already.
</para>
<para>
The first schema in the seach path that exists is the default
location for creating new objects. That is the reason that by
default objects are created in the public schema. When objects
are referenced in any other context without schema qualification
(table modification, data modification, or query commands) the
search path is traversed until a matching object is found.
Therefore, in the default configuration, any unqualified access
again can only refer to the public schema.
</para>
<para>
To put our new schema in the path, we use
<programlisting>
SET search_path TO myschema,public;
</programlisting>
(We omit the <literal>$user</literal> here because we have no
immediate need for it.) And then we can access the table without
schema qualification:
<programlisting>
DROP TABLE mytable;
</programlisting>
Also, since <literal>myschema</literal> is the first element in
the path, new objects would by default be created in it.
</para>
<para>
We could also have written
<programlisting>
SET search_path TO myschema;
</programlisting>
Then we no longer have access to the public schema without
explicit qualification. There is nothing special about the public
schema except that it exists by default. It can be dropped, too.
</para>
<para>
See also <xref linkend="set-search-path"> for other ways to access
the schema search path.
</para>
<para>
The search path works in the same way for datatype names, function names,
and operator names as it does for table names. Datatype and function
names can be qualified in exactly the same way as table names. If you
need to write a qualified operator name in an expression, there is a
special provision: you must write
<synopsis>
<literal>OPERATOR(</><replaceable>schema</><literal>.</><replaceable>operator</><literal>)</>
</synopsis>
This is needed to avoid syntactic ambiguity. An example is
<programlisting>
SELECT 3 OPERATOR(pg_catalog.+) 4;
</programlisting>
In practice one usually relies on the search path for operators,
so as not to have to write anything so ugly as that.
</para>
</sect2>
<sect2 id="ddl-schemas-priv">
<title>Schemas and Privileges</title>
<para>
By default, users cannot see the objects in schemas they do not
own. To allow that, the owner of the schema needs to grant the
<literal>USAGE</literal> privilege on the schema. To allow users
to make use of the objects in the schema, additional privileges
may need to be granted, as appropriate for the object.
</para>
<para>
A user can also be allowed to create objects in someone else's
schema. To allow that, the <literal>CREATE</literal> privilege on
the schema needs to be granted. Note that by default, everyone
has the <literal>CREATE</literal> privilege on the schema
<literal>public</literal>. This allows all users that manage to
connect to a given database to create objects there. If you do
not want to allow that, you can revoke that privilege:
<programlisting>
REVOKE CREATE ON public FROM PUBLIC;
</programlisting>
(The first <quote>public</quote> is the schema, the second
<quote>public</quote> means <quote>every user</quote>. In the
first sense it is an identifier, in the second sense it is a
reserved word, hence the different capitalization; recall the
guidelines from <xref linkend="sql-syntax-identifiers">.)
</para>
</sect2>
<sect2>
<title>The System Catalog Schema</title>
<para>
In addition to <literal>public</> and user-created schemas, each
database contains a <literal>pg_catalog</> schema, which contains
the system tables and all the built-in datatypes, functions, and
operators. <literal>pg_catalog</> is always effectively part of
the search path. If it is not named explicitly in the path then
it is implicitly searched <emphasis>before</> searching the path's
schemas. This ensures that built-in names will always be
findable. However, you may explicitly place
<literal>pg_catalog</> at the end of your search path if you
prefer to have user-defined names override built-in names.
</para>
<para>
In <productname>PostgreSQL</productname> versions before 7.3,
table names beginning with <literal>pg_</> were reserved. This is
no longer true: you may create such a table name if you wish, in
any non-system schema. However, it's best to continue to avoid
such names, to ensure that you won't suffer a conflict if some
future version defines a system catalog named the same as your
table. (With the default search path, an unqualified reference to
your table name would be resolved as the system catalog instead.)
System catalogs will continue to follow the convention of having
names beginning with <literal>pg_</>, so that they will not
conflict with unqualified user-table names so long as users avoid
the <literal>pg_</> prefix.
</para>
</sect2>
<sect2 id="ddl-schemas-patterns">
<title>Usage Patterns</title>
<para>
Schemas can be used to organize your data in many ways. There are
a few usage patterns are recommended and are easily supported by
the default configuration:
<itemizedlist>
<listitem>
<para>
If you do not create any schemas then all users access the
public schema implicitly. This simulates the situation where
schemas are not available at all. This setup is mainly
recommended when there is only a single user or few cooperating
users in a database. This setup also allows smooth transition
from the non-schema-aware world.
</para>
</listitem>
<listitem>
<para>
You can create a schema for each user with the same name as
that user. Recall that the default search path starts with
<literal>$user</literal>, which resolves to the user name.
Therefore, if each user has a separate schema, they access their
own schemas by default.
</para>
<para>
If you use this setup then you might also want to revoke access
to the public schema (or drop it altogether), so users are
truly constrained to their own schemas.
</para>
</listitem>
<listitem>
<para>
To install shared applications (tables to be used by everyone,
additional functions provided by third parties, etc.), put them
into separate schemas. Remember to grant appropriate
privileges to allow the other users to access them. Users can
then refer to these additional object by qualifying the names
with a schema name, or they can put the additional schemas into
their path, as they choose.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2 id="ddl-schemas-portability">
<title>Portability</title>
<para>
In the SQL standard, the notion of objects in the same schema
being owned by different users does not exist. Moreover, some
implementations don't allow you to create schemas that have a
different name than their owner. In fact, the concepts of schema
and user are nearly equivalent in a database system that
implements only the basic schema support specified in the
standard. Therefore, many users consider qualified names to
really consist of
<literal><replaceable>username</>.<replaceable>tablename</></literal>.
This is also supported by PostgreSQL if you create a per-user
schema for every user.
</para>
<para>
Also, there is no concept of a <literal>public</> schema in the
SQL standard. For maximum conformance to the standard, you should
not use (perhaps even remove) the <literal>public</> schema.
</para>
<para>
Of course, some SQL database systems might not implement schemas
at all, or provide namespace support by allowing (possibly
limited) cross-database access. If you need to work with those
systems, then maximum portability would be achieved by not using
schemas at all.
</para>
</sect2>
</sect1>
<sect1 id="ddl-others">

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.68 2002/08/23 04:27:19 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.69 2002/09/12 22:05:36 petere Exp $
-->
<chapter id="sql-syntax">
@ -581,7 +581,7 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
<listitem>
<para>
The period (<literal>.</literal>) is used in floating-point
constants, and to separate table and column names.
constants, and to separate schema, table, and column names.
</para>
</listitem>
</itemizedlist>
@ -815,307 +815,6 @@ SELECT 3 OPERATOR(pg_catalog.+) 4;
</sect2>
</sect1>
<sect1 id="sql-naming">
<title>Schemas and Naming Conventions</title>
<indexterm>
<primary>schemas</primary>
</indexterm>
<indexterm>
<primary>search path</primary>
</indexterm>
<indexterm>
<primary>namespaces</primary>
</indexterm>
<para>
A <productname>PostgreSQL</productname> database cluster (installation)
contains one or more named databases. Users and groups of users are
shared across the entire cluster, but no other data is shared across
databases. Any given client connection to the server can access
only the data in a single database, the one specified in the connection
request.
</para>
<note>
<para>
Users of a cluster do not necessarily have the privilege to access every
database in the cluster. Sharing of user names means that there
cannot be different users named, say, <literal>joe</> in two databases
in the same cluster; but the system can be configured to allow
<literal>joe</> access to only some of the databases.
</para>
</note>
<sect2>
<title>Schema Object Names</title>
<para>
A database contains one or more named <firstterm>schemas</>, which
in turn contain tables. Schemas also contain other kinds of named
objects, including datatypes, functions, and operators. The same
object name can be used in different schemas without conflict; for
example, both <literal>schema1</> and <literal>myschema</> may
contain tables named <literal>mytable</>. Unlike databases, schemas
are not rigidly separated: a user may access objects in any of the
schemas in the database he is connected to, if he has privileges
to do so.
</para>
<indexterm>
<primary>qualified names</primary>
</indexterm>
<indexterm>
<primary>names</primary>
<secondary>qualified</secondary>
</indexterm>
<para>
To name a table precisely, write a <firstterm>qualified name</> consisting
of the schema name and table name separated by a dot:
<synopsis>
<replaceable>schema</><literal>.</><replaceable>table</>
</synopsis>
Actually, the even more general syntax
<synopsis>
<replaceable>database</><literal>.</><replaceable>schema</><literal>.</><replaceable>table</>
</synopsis>
can be used too, but at present this is just for pro-forma compliance
with the SQL standard; if you write a database name it must be the
same as the database you are connected to.
</para>
<indexterm>
<primary>unqualified names</primary>
</indexterm>
<indexterm>
<primary>names</primary>
<secondary>unqualified</secondary>
</indexterm>
<para>
Qualified names are tedious to write, and it's often best not to
wire a particular schema name into applications anyway. Therefore
tables are often referred to by <firstterm>unqualified names</>,
which consist of just the table name. The system determines which table
is meant by following a <firstterm>search path</>, which is a list
of schemas to look in. The first matching table in the search path
is taken to be the one wanted. If there is no match in the search
path, an error is reported, even if matching table names exist
in other schemas in the database.
</para>
<para>
The first schema named in the search path is called the current schema.
Aside from being the first schema searched, it is also the schema in
which new tables will be created if the <command>CREATE TABLE</>
command does not specify a schema name.
</para>
<para>
The search path works in the same way for datatype names, function names,
and operator names as it does for table names. Datatype and function
names can be qualified in exactly the same way as table names. If you
need to write a qualified operator name in an expression, there is a
special provision: you must write
<synopsis>
<literal>OPERATOR(</><replaceable>schema</><literal>.</><replaceable>operator</><literal>)</>
</synopsis>
This is needed to avoid syntactic ambiguity. An example is
<programlisting>
SELECT 3 OPERATOR(pg_catalog.+) 4;
</programlisting>
In practice one usually relies on the search path for operators,
so as not to have to write anything so ugly as that.
</para>
<para>
The standard search path in <productname>PostgreSQL</productname>
contains first the schema having the same name as the session user
(if it exists), and second the schema named <literal>public</>
(if it exists, which it does by default). This arrangement allows
a flexible combination of private and shared tables. If no per-user
schemas are created then all user tables will exist in the shared
<literal>public</> schema, providing behavior that is backwards-compatible
with pre-7.3 <productname>PostgreSQL</productname> releases.
</para>
<note>
<para>
There is no concept of a <literal>public</> schema in the SQL standard.
To achieve closest conformance to the standard, the DBA should
create per-user schemas for every user, and not use (perhaps even
remove) the <literal>public</> schema.
</para>
</note>
<para>
In addition to <literal>public</> and user-created schemas, each database
contains a
<literal>pg_catalog</> schema, which contains the system tables
and all the built-in datatypes, functions, and operators.
<literal>pg_catalog</> is always effectively part of the search path.
If it is not named explicitly in the path then it is implicitly searched
<emphasis>before</> searching the path's schemas. This ensures that
built-in names will always be findable. However, you may explicitly
place <literal>pg_catalog</> at the end of your search path if you
prefer to have user-defined names override built-in names.
</para>
<para>
The search path is determined by the GUC variable SEARCH_PATH and
may be changed at any time. See <xref linkend="set-search-path">.
</para>
</sect2>
<sect2 id="sql-reserved-names">
<title>Reserved names</title>
<indexterm>
<primary>reserved names</primary>
</indexterm>
<indexterm>
<primary>names</primary>
<secondary>reserved</secondary>
</indexterm>
<para>
There are several restrictions on the names that can be chosen for
user-defined database objects. These restrictions vary depending
on the kind of object. (Note that these restrictions are
separate from whether the name is a key word or not; quoting a
name will not allow you to escape these restrictions.)
</para>
<para>
Schema names beginning with <literal>pg_</> are reserved for system
purposes and may not be created by users.
</para>
<para>
In <productname>PostgreSQL</productname> versions before 7.3, table
names beginning with <literal>pg_</> were reserved. This is no longer
true: you may create such a table name if you wish, in any non-system
schema. However, it's best to continue to avoid such names,
to ensure that you won't suffer a conflict if some future version
defines a system catalog named the same as your table. (With the
default search path, an unqualified reference to your table name
would be resolved as the system catalog instead.) System catalogs will
continue to follow the convention of having names beginning with
<literal>pg_</>, so that they will not conflict with unqualified
user-table names so long as users avoid the <literal>pg_</> prefix.
</para>
<para>
Every table has several <firstterm>system columns</> that are
implicitly defined by the system. Therefore, these names cannot
be used as names of user-defined columns:
<indexterm>
<primary>columns</primary>
<secondary>system columns</secondary>
</indexterm>
<variablelist>
<varlistentry>
<term><structfield>oid</></term>
<listitem>
<para>
<indexterm>
<primary>OID</primary>
</indexterm>
The object identifier (object ID) of a row. This is a serial number
that is automatically added by <productname>PostgreSQL</productname> to all table rows (unless
the table was created WITHOUT OIDS, in which case this column is
not present). See <xref linkend="datatype-oid"> for more info.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>tableoid</></term>
<listitem>
<para>
The OID of the table containing this row. This attribute is
particularly handy for queries that select from inheritance
hierarchies, since without it, it's difficult to tell which
individual table a row came from. The
<structfield>tableoid</structfield> can be joined against the
<structfield>oid</structfield> column of
<classname>pg_class</classname> to obtain the table name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>xmin</></term>
<listitem>
<para>
The identity (transaction ID) of the inserting transaction for
this tuple. (Note: A tuple is an individual state of a row;
each update of a row creates a new tuple for the same logical row.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>cmin</></term>
<listitem>
<para>
The command identifier (starting at zero) within the inserting
transaction.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>xmax</></term>
<listitem>
<para>
The identity (transaction ID) of the deleting transaction,
or zero for an undeleted tuple. It is possible for this field
to be nonzero in a visible tuple: that usually indicates that the
deleting transaction hasn't committed yet, or that an attempted
deletion was rolled back.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>cmax</></term>
<listitem>
<para>
The command identifier within the deleting transaction, or zero.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><structfield>ctid</></term>
<listitem>
<para>
The physical location of the tuple within its table.
Note that although the <structfield>ctid</structfield>
can be used to locate the tuple very quickly, a row's
<structfield>ctid</structfield> will change each time it is updated
or moved by <command>VACUUM FULL</>.
Therefore <structfield>ctid</structfield> is useless as a long-term
row identifier.
The OID, or even better a user-defined serial number, should
be used to identify logical rows.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</sect2>
</sect1>
<sect1 id="sql-expressions">
<title>Value Expressions</title>

View File

@ -232,7 +232,7 @@ Select the operators to be considered from the
<classname>pg_operator</classname> system catalog. If an unqualified
operator name is used (the usual case), the operators
considered are those of the right name and argument count that are
visible in the current search path (see <xref linkend="sql-naming">).
visible in the current search path (see <xref linkend="ddl-schemas-path">).
If a qualified operator name was given, only operators in the specified
schema are considered.
</para>
@ -497,7 +497,7 @@ Select the functions to be considered from the
<classname>pg_proc</classname> system catalog. If an unqualified
function name is used, the functions
considered are those of the right name and argument count that are
visible in the current search path (see <xref linkend="sql-naming">).
visible in the current search path (see <xref linkend="ddl-schemas-path">).
If a qualified function name was given, only functions in the specified
schema are considered.
</para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/user-manag.sgml,v 1.14 2002/08/16 04:47:43 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/user-manag.sgml,v 1.15 2002/09/12 22:05:36 petere Exp $
-->
<chapter id="user-manag">
@ -139,6 +139,8 @@ ALTER GROUP <replaceable>name</replaceable> DROP USER <replaceable>uname1</repla
<sect1 id="privileges">
<title>Privileges</title>
<comment>Being moved to User's Guide. Will eventually disappear here.</comment>
<para>
When a database object is created, it is assigned an owner. The
owner is the user that executed the creation statement. To change