Commit bf56f075 authored by Tom Lane's avatar Tom Lane

Make OIDs optional, per discussions in pghackers. WITH OIDS is still the

default, but OIDS are removed from many system catalogs that don't need them.
Some interesting side effects: TOAST pointers are 20 bytes not 32 now;
pg_description has a three-column key instead of one.

Bugs fixed in passing: BINARY cursors work again; pg_class.relhaspkey
has some usefulness; pg_dump dumps comments on indexes, rules, and
triggers in a valid order.

initdb forced.
parent d062f0f4
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
-- darcy@druid.net -- darcy@druid.net
-- http://www.druid.net/darcy/ -- http://www.druid.net/darcy/
-- --
-- $Header: /cvsroot/pgsql/contrib/chkpass/Attic/chkpass.sql,v 1.1 2001/05/03 12:32:13 darcy Exp $ -- $Header: /cvsroot/pgsql/contrib/chkpass/Attic/chkpass.sql,v 1.2 2001/08/10 18:57:32 tgl Exp $
-- best viewed with tabs set to 4 -- best viewed with tabs set to 4
-- %%PGDIR%% changed to your local directory where modules is -- %%PGDIR%% changed to your local directory where modules is
-- --
...@@ -73,9 +73,7 @@ create operator <> ( ...@@ -73,9 +73,7 @@ create operator <> (
procedure = ne procedure = ne
); );
INSERT INTO pg_description (objoid, description) COMMENT ON TYPE chkpass IS 'password type with checks';
SELECT oid, 'password type with checks'
FROM pg_type WHERE typname = 'chkpass';
-- --
-- eof -- eof
......
...@@ -9,10 +9,10 @@ it on anything but an empty database, such as template1. ...@@ -9,10 +9,10 @@ it on anything but an empty database, such as template1.
Uses pgeasy library. Uses pgeasy library.
Run on an empty database, it returns the system join relationships (shown Run on an empty database, it returns the system join relationships (shown
below for 7.1). Note that unexpected matches may indicate bogus entries below for 7.2). Note that unexpected matches may indicate bogus entries
in system tables --- don't accept a peculiar match without question. in system tables --- don't accept a peculiar match without question.
In particular, a field shown as joining to more than one target table is In particular, a field shown as joining to more than one target table is
probably messed up. In 7.1, the *only* field that should join to more probably messed up. In 7.2, the *only* field that should join to more
than one target is pg_description.objoid. (Running make_oidjoins_check than one target is pg_description.objoid. (Running make_oidjoins_check
is an easy way to spot fields joining to more than one table, BTW.) is an easy way to spot fields joining to more than one table, BTW.)
...@@ -27,9 +27,8 @@ revision in the patterns of cross-links between system tables. ...@@ -27,9 +27,8 @@ revision in the patterns of cross-links between system tables.
(Ideally we'd just regenerate the script as part of the regression (Ideally we'd just regenerate the script as part of the regression
tests themselves, but that seems too slow...) tests themselves, but that seems too slow...)
NOTE: in 7.1, make_oidjoins_check produces two bogus join checks, one for NOTE: in 7.2, make_oidjoins_check produces one bogus join check, for
pg_database.datlastsysoid => pg_description.oid and one for pg_class.relfilenode => pg_class.oid. This is an artifact and should not
pg_class.relfilenode => pg_class.oid. These are artifacts and should not
be added to the oidjoins regress test. be added to the oidjoins regress test.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
...@@ -41,13 +40,13 @@ Join pg_aggregate.aggtranstype => pg_type.oid ...@@ -41,13 +40,13 @@ Join pg_aggregate.aggtranstype => pg_type.oid
Join pg_aggregate.aggfinaltype => pg_type.oid Join pg_aggregate.aggfinaltype => pg_type.oid
Join pg_am.amgettuple => pg_proc.oid Join pg_am.amgettuple => pg_proc.oid
Join pg_am.aminsert => pg_proc.oid Join pg_am.aminsert => pg_proc.oid
Join pg_am.amdelete => pg_proc.oid
Join pg_am.ambeginscan => pg_proc.oid Join pg_am.ambeginscan => pg_proc.oid
Join pg_am.amrescan => pg_proc.oid Join pg_am.amrescan => pg_proc.oid
Join pg_am.amendscan => pg_proc.oid Join pg_am.amendscan => pg_proc.oid
Join pg_am.ammarkpos => pg_proc.oid Join pg_am.ammarkpos => pg_proc.oid
Join pg_am.amrestrpos => pg_proc.oid Join pg_am.amrestrpos => pg_proc.oid
Join pg_am.ambuild => pg_proc.oid Join pg_am.ambuild => pg_proc.oid
Join pg_am.ambulkdelete => pg_proc.oid
Join pg_am.amcostestimate => pg_proc.oid Join pg_am.amcostestimate => pg_proc.oid
Join pg_amop.amopid => pg_am.oid Join pg_amop.amopid => pg_am.oid
Join pg_amop.amopclaid => pg_opclass.oid Join pg_amop.amopclaid => pg_opclass.oid
...@@ -61,6 +60,7 @@ Join pg_class.reltype => pg_type.oid ...@@ -61,6 +60,7 @@ Join pg_class.reltype => pg_type.oid
Join pg_class.relam => pg_am.oid Join pg_class.relam => pg_am.oid
Join pg_class.reltoastrelid => pg_class.oid Join pg_class.reltoastrelid => pg_class.oid
Join pg_class.reltoastidxid => pg_class.oid Join pg_class.reltoastidxid => pg_class.oid
Join pg_description.classoid => pg_class.oid
Join pg_index.indexrelid => pg_class.oid Join pg_index.indexrelid => pg_class.oid
Join pg_index.indrelid => pg_class.oid Join pg_index.indrelid => pg_class.oid
Join pg_opclass.opcdeftype => pg_type.oid Join pg_opclass.opcdeftype => pg_type.oid
...@@ -78,7 +78,9 @@ Join pg_proc.prolang => pg_language.oid ...@@ -78,7 +78,9 @@ Join pg_proc.prolang => pg_language.oid
Join pg_proc.prorettype => pg_type.oid Join pg_proc.prorettype => pg_type.oid
Join pg_rewrite.ev_class => pg_class.oid Join pg_rewrite.ev_class => pg_class.oid
Join pg_statistic.starelid => pg_class.oid Join pg_statistic.starelid => pg_class.oid
Join pg_statistic.staop => pg_operator.oid Join pg_statistic.staop1 => pg_operator.oid
Join pg_statistic.staop2 => pg_operator.oid
Join pg_statistic.staop3 => pg_operator.oid
Join pg_trigger.tgrelid => pg_class.oid Join pg_trigger.tgrelid => pg_class.oid
Join pg_trigger.tgfoid => pg_proc.oid Join pg_trigger.tgfoid => pg_proc.oid
Join pg_type.typrelid => pg_class.oid Join pg_type.typrelid => pg_class.oid
......
...@@ -38,7 +38,6 @@ main(int argc, char **argv) ...@@ -38,7 +38,6 @@ main(int argc, char **argv)
FROM pg_class c, pg_attribute a, pg_type t \ FROM pg_class c, pg_attribute a, pg_type t \
WHERE a.attnum > 0 AND \ WHERE a.attnum > 0 AND \
relkind = 'r' AND \ relkind = 'r' AND \
relhasrules = 'f' AND \
(typname = 'oid' OR \ (typname = 'oid' OR \
typname = 'regproc') AND \ typname = 'regproc') AND \
a.attrelid = c.oid AND \ a.attrelid = c.oid AND \
...@@ -52,8 +51,7 @@ main(int argc, char **argv) ...@@ -52,8 +51,7 @@ main(int argc, char **argv)
DECLARE c_relations BINARY CURSOR FOR \ DECLARE c_relations BINARY CURSOR FOR \
SELECT relname \ SELECT relname \
FROM pg_class c \ FROM pg_class c \
WHERE relkind = 'r' AND \ WHERE relkind = 'r' AND relhasoids \
relhasrules = 'f' \
ORDER BY 1; \ ORDER BY 1; \
"); ");
doquery("FETCH ALL IN c_relations"); doquery("FETCH ALL IN c_relations");
...@@ -71,14 +69,14 @@ main(int argc, char **argv) ...@@ -71,14 +69,14 @@ main(int argc, char **argv)
sprintf(query, "\ sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \ DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*) \ SELECT count(*) \
FROM %s t1, %s t2 \ FROM \"%s\" t1, \"%s\" t2 \
WHERE t1.%s = t2.oid ", relname, relname2, attname); WHERE t1.\"%s\" = t2.oid ", relname, relname2, attname);
else else
sprintf(query, "\ sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \ DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*) \ SELECT count(*) \
FROM %s t1, %s t2 \ FROM \"%s\" t1, \"%s\" t2 \
WHERE RegprocToOid(t1.%s) = t2.oid ", relname, relname2, attname); WHERE RegprocToOid(t1.\"%s\") = t2.oid ", relname, relname2, attname);
doquery(query); doquery(query);
doquery("FETCH ALL IN c_matches"); doquery("FETCH ALL IN c_matches");
......
#! /bin/sh #! /bin/sh
# You first run findoidjoins on the template1 database, and send that # You first run findoidjoins on the template1 database, and send that
# output into this file to generate a list of SQL statements. # output into this script to generate a list of SQL statements.
# NOTE: any field that findoidjoins thinks joins to more than one table # NOTE: any field that findoidjoins thinks joins to more than one table
# will NOT be checked by the output of this script. You should be # will NOT be checked by the output of this script. You should be
...@@ -41,7 +41,7 @@ $AWK -F'[ \.]' '\ ...@@ -41,7 +41,7 @@ $AWK -F'[ \.]' '\
} }
{ {
printf "\ printf "\
SELECT oid, %s.%s \n\ SELECT ctid, %s.%s \n\
FROM %s \n\ FROM %s \n\
WHERE %s.%s != 0 AND \n\ WHERE %s.%s != 0 AND \n\
NOT EXISTS(SELECT * FROM %s AS t1 WHERE t1.oid = %s.%s);\n", NOT EXISTS(SELECT * FROM %s AS t1 WHERE t1.oid = %s.%s);\n",
......
...@@ -11,42 +11,27 @@ BEGIN TRANSACTION; ...@@ -11,42 +11,27 @@ BEGIN TRANSACTION;
CREATE FUNCTION _int_contains(_int4, _int4) RETURNS bool CREATE FUNCTION _int_contains(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description) COMMENT ON FUNCTION _int_contains(_int4, _int4) IS 'contains';
SELECT oid, 'contains'::text
FROM pg_proc
WHERE proname = '_int_contains'::name;
CREATE FUNCTION _int_contained(_int4, _int4) RETURNS bool CREATE FUNCTION _int_contained(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description) COMMENT ON FUNCTION _int_contained(_int4, _int4) IS 'contained in';
SELECT oid, 'contained in'::text
FROM pg_proc
WHERE proname = '_int_contained'::name;
CREATE FUNCTION _int_overlap(_int4, _int4) RETURNS bool CREATE FUNCTION _int_overlap(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description) COMMENT ON FUNCTION _int_overlap(_int4, _int4) IS 'overlaps';
SELECT oid, 'overlaps'::text
FROM pg_proc
WHERE proname = '_int_overlap'::name;
CREATE FUNCTION _int_same(_int4, _int4) RETURNS bool CREATE FUNCTION _int_same(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description) COMMENT ON FUNCTION _int_same(_int4, _int4) IS 'same as';
SELECT oid, 'same as'::text
FROM pg_proc
WHERE proname = '_int_same'::name;
CREATE FUNCTION _int_different(_int4, _int4) RETURNS bool CREATE FUNCTION _int_different(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description) COMMENT ON FUNCTION _int_different(_int4, _int4) IS 'different';
SELECT oid, 'different'::text
FROM pg_proc
WHERE proname = '_int_different'::name;
-- support routines for indexing -- support routines for indexing
......
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.19 2001/07/15 22:48:15 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.20 2001/08/10 18:57:32 tgl Exp $
--> -->
<chapter id="catalogs"> <chapter id="catalogs">
...@@ -532,9 +532,9 @@ ...@@ -532,9 +532,9 @@
<para> <para>
<structname>pg_class</structname> catalogues tables and mostly <structname>pg_class</structname> catalogues tables and mostly
everything else that has columns or is otherwise similar to a everything else that has columns or is otherwise similar to a
table. This includes indexes (but see table. This includes indexes (but see also
<structname>pg_index</structname>), sequences, views, and some <structname>pg_index</structname>), sequences, views, and some
kinds of special relation kinds. Below, when we mean all of these kinds of special relation. Below, when we mean all of these
kinds of objects we speak of <quote>relations</quote>. Not all kinds of objects we speak of <quote>relations</quote>. Not all
fields are meaningful for all relation types. fields are meaningful for all relation types.
</para> </para>
...@@ -565,8 +565,8 @@ ...@@ -565,8 +565,8 @@
<entry><type>oid</type></entry> <entry><type>oid</type></entry>
<entry>pg_type.oid</entry> <entry>pg_type.oid</entry>
<entry> <entry>
The data type that corresponds to this table (not functional, The OID of the data type that corresponds to this table, if any
only set for system tables) (zero for indexes, which have no pg_type entry)
</entry> </entry>
</row> </row>
...@@ -631,14 +631,19 @@ ...@@ -631,14 +631,19 @@
<entry>reltoastidxid</entry> <entry>reltoastidxid</entry>
<entry><type>oid</type></entry> <entry><type>oid</type></entry>
<entry>pg_class.oid</entry> <entry>pg_class.oid</entry>
<entry>Oid of the index on the TOAST table for this table, 0 if none</entry> <entry>
For a TOAST table, the OID of its index. 0 if not a TOAST table.
</entry>
</row> </row>
<row> <row>
<entry>relhasindex</entry> <entry>relhasindex</entry>
<entry><type>bool</type></entry> <entry><type>bool</type></entry>
<entry></entry> <entry></entry>
<entry>True if this is a table and it has at least one index</entry> <entry>True if this is a table and it has (or recently had) any indexes.
This is set by CREATE INDEX, but not cleared immediately by DROP INDEX.
VACUUM clears relhasindex if it finds the table has no indexes.
</entry>
</row> </row>
<row> <row>
...@@ -664,7 +669,7 @@ ...@@ -664,7 +669,7 @@
<entry><type>int2</type></entry> <entry><type>int2</type></entry>
<entry></entry> <entry></entry>
<entry> <entry>
Number of columns in the relation, besides system columns. Number of user columns in the relation (system columns not counted).
There must be this many corresponding entries in There must be this many corresponding entries in
<structname>pg_attribute</structname>. See also <structname>pg_attribute</structname>. See also
<structname>pg_attribute</structname>.<structfield>attnum</structfield>. <structname>pg_attribute</structname>.<structfield>attnum</structfield>.
...@@ -695,14 +700,30 @@ ...@@ -695,14 +700,30 @@
<entry>relukeys</entry> <entry>relukeys</entry>
<entry><type>int2</type></entry> <entry><type>int2</type></entry>
<entry></entry> <entry></entry>
<entry>unused (<emphasis>Not</emphasis> the number of unique keys or something.)</entry> <entry>unused (<emphasis>Not</emphasis> the number of unique keys)</entry>
</row> </row>
<row> <row>
<entry>relfkeys</entry> <entry>relfkeys</entry>
<entry><type>int2</type></entry> <entry><type>int2</type></entry>
<entry></entry> <entry></entry>
<entry>Number foreign keys on the table</entry> <entry>unused (<emphasis>Not</emphasis> the number of foreign keys on the table)</entry>
</row>
<row>
<entry>relrefs</entry>
<entry><type>int2</type></entry>
<entry></entry>
<entry>unused</entry>
</row>
<row>
<entry>relhasoids</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>
True if we generate an OID for each row of the relation.
</entry>
</row> </row>
<row> <row>
...@@ -710,8 +731,7 @@ ...@@ -710,8 +731,7 @@
<entry><type>bool</type></entry> <entry><type>bool</type></entry>
<entry></entry> <entry></entry>
<entry> <entry>
unused (No, this does not say whether the table has a primary True if the table has (or once had) a primary key.
key. It's really unused.)
</entry> </entry>
</row> </row>
...@@ -726,7 +746,7 @@ ...@@ -726,7 +746,7 @@
<entry>relhassubclass</entry> <entry>relhassubclass</entry>
<entry><type>bool</type></entry> <entry><type>bool</type></entry>
<entry></entry> <entry></entry>
<entry>At least one table inherits this one</entry> <entry>At least one table inherits from this one</entry>
</row> </row>
<row> <row>
...@@ -874,6 +894,23 @@ ...@@ -874,6 +894,23 @@
<entry>The oid of the object this description pertains to</entry> <entry>The oid of the object this description pertains to</entry>
</row> </row>
<row>
<entry>classoid</entry>
<entry><type>oid</type></entry>
<entry>pg_class.oid</entry>
<entry>The oid of the system catalog this object appears in</entry>
</row>
<row>
<entry>objsubid</entry>
<entry><type>int4</type></entry>
<entry></entry>
<entry>For a comment on a table attribute, this is the attribute's
column number (the objoid and classoid refer to the table itself).
For all other object types, this field is presently zero.
</entry>
</row>
<row> <row>
<entry>description</entry> <entry>description</entry>
<entry><type>text</type></entry> <entry><type>text</type></entry>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.42 2001/05/03 17:50:55 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.43 2001/08/10 18:57:32 tgl Exp $
Postgres documentation Postgres documentation
--> -->
...@@ -25,8 +25,9 @@ Postgres documentation ...@@ -25,8 +25,9 @@ Postgres documentation
<synopsis> <synopsis>
CREATE [ TEMPORARY | TEMP ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( CREATE [ TEMPORARY | TEMP ] TABLE <replaceable class="PARAMETER">table_name</replaceable> (
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">type</replaceable> [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ] { <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">type</replaceable> [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
| <replaceable>table_constraint</replaceable> } [, ... ] | <replaceable>table_constraint</replaceable> } [, ... ] )
) [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ] [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ]
where <replaceable class="PARAMETER">column_constraint</replaceable> can be: where <replaceable class="PARAMETER">column_constraint</replaceable> can be:
[ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ] [ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
...@@ -108,6 +109,18 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> can be: ...@@ -108,6 +109,18 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> can be:
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>WITH OIDS or WITHOUT OIDS</term>
<listitem>
<para>
This optional clause specifies whether rows of the new table should
have OIDs (object identifiers) assigned to them. The default is
WITH OIDS. (If the new table inherits from any tables that have OIDs,
then WITH OIDS is forced even if the command says WITHOUT OIDS.)
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="PARAMETER">constraint_name</replaceable></term> <term><replaceable class="PARAMETER">constraint_name</replaceable></term>
<listitem> <listitem>
...@@ -303,6 +316,49 @@ INHERITS ( <replaceable class="PARAMETER">parent_table</replaceable> [, ... ] ) ...@@ -303,6 +316,49 @@ INHERITS ( <replaceable class="PARAMETER">parent_table</replaceable> [, ... ] )
</para> </para>
</refsect1> </refsect1>
<refsect1 id="R1-SQL-OIDSCLAUSE-1">
<title id="R1-SQL-OIDSCLAUSE-1-TITLE">
OIDS Clause
</title>
<para>
<synopsis>
WITH OIDS | WITHOUT OIDS
</synopsis>
</para>
<para>
This clause controls whether an OID (object ID) is generated and assigned
to each row inserted into the table. The default is WITH OIDS.
Specifying WITHOUT OIDS allows the user to suppress generation of
OIDs for rows of a table. This may be worthwhile for large
tables, since it will reduce OID consumption and thereby postpone
wraparound of the 32-bit OID counter. Once the counter wraps around,
uniqueness of OIDs can no longer be assumed, which considerably reduces
their usefulness.
</para>
<para>
Whenever an application makes use of OIDs to identify specific rows of
a table, it is recommended that you create a unique index on OID for
that table, to ensure that OIDs in the table will indeed uniquely
identify rows even after counter wraparound. (An index on OID is needed
anyway for fast lookup of rows by OID.) Avoid assuming that OIDs are
unique across tables --- if you need a database-wide unique identifier,
use the combination of tableoid and row OID for the purpose. (It is
likely that future Postgres releases will use a separate OID counter
for each table, so that it will be <emphasis>necessary</> not optional
to include tableoid to have a unique identifier database-wide.)
</para>
<tip>
<para>
WITHOUT OIDS is not recommended for tables with no primary key, since
without either an OID or a unique data key, it is difficult to identify
specific rows.
</para>
</tip>
</refsect1>
<refsect1 id="R1-SQL-DEFAULTCLAUSE-1"> <refsect1 id="R1-SQL-DEFAULTCLAUSE-1">
<title id="R1-SQL-DEFAULTCLAUSE-1-TITLE"> <title id="R1-SQL-DEFAULTCLAUSE-1-TITLE">
DEFAULT Clause DEFAULT Clause
...@@ -2098,6 +2154,18 @@ ALTER DOMAIN cities ...@@ -2098,6 +2154,18 @@ ALTER DOMAIN cities
supported by <productname>Postgres</productname>. supported by <productname>Postgres</productname>.
</para> </para>
</refsect3> </refsect3>
<refsect3 id="R3-SQL-INHERITANCE-1">
<title>
Object IDs
</title>
<para>
The <productname>Postgres</productname> concept of OIDs is not
standard. SQL99 (but not SQL92) has a notion of object ID, but
the syntax and semantics are different --- SQL99 associates OIDs
with individual values, not with rows.
</para>
</refsect3>
</refsect2> </refsect2>
</refsect1> </refsect1>
</refentry> </refentry>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.43 2001/06/19 22:39:08 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.44 2001/08/10 18:57:32 tgl Exp $
--> -->
<chapter id="sql-syntax"> <chapter id="sql-syntax">
...@@ -641,8 +641,9 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> ) ...@@ -641,8 +641,9 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
<primary>OID</primary> <primary>OID</primary>
</indexterm> </indexterm>
The unique identifier (object ID) of a row. This is a serial number The unique identifier (object ID) of a row. This is a serial number
that is added by Postgres to all rows automatically. OIDs are not that is automatically added by Postgres to all table rows (unless
reused and are 32-bit quantities. the table was created WITHOUT OIDS, in which case this column is
not present).
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -686,8 +687,10 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> ) ...@@ -686,8 +687,10 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
<listitem> <listitem>
<para> <para>
The identity (transaction ID) of the deleting transaction, The identity (transaction ID) of the deleting transaction,
or zero for an undeleted tuple. In practice, this is never nonzero or zero for an undeleted tuple. It is possible for this field
for a visible tuple. to be nonzero in a visible tuple: that indicates that the
deleting transaction hasn't committed yet, or that an attempted
deletion was rolled back.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -697,7 +700,6 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> ) ...@@ -697,7 +700,6 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
<listitem> <listitem>
<para> <para>
The command identifier within the deleting transaction, or zero. The command identifier within the deleting transaction, or zero.
Again, this is never nonzero for a visible tuple.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -720,10 +722,27 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> ) ...@@ -720,10 +722,27 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
</variablelist> </variablelist>
</para> </para>
<para>
OIDs are 32-bit quantities and are assigned from a single cluster-wide
counter. In a large or long-lived database, it is possible for the
counter to wrap around. Hence, it is bad practice to assume that OIDs
are unique, unless you take steps to ensure that they are unique.
Recommended practice when using OIDs for row identification is to create
a unique index on the OID column of each table for which the OID will be
used. Never assume that OIDs are unique across tables; use the
combination of tableoid and row OID if you need a database-wide
identifier. (Future releases of Postgres are likely to use a separate
OID counter for each table, so that tableoid <emphasis>must</> be
included to arrive at a globally unique identifier.)
</para>
<para>
Transaction and command identifiers are 32-bit quantities.
</para>
<para> <para>
For further information on the system attributes consult For further information on the system attributes consult
<xref linkend="STON87a" endterm="STON87a">. <xref linkend="STON87a" endterm="STON87a">.
Transaction and command identifiers are 32-bit quantities.
</para> </para>
</sect1> </sect1>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.123 2001/07/12 04:11:12 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.124 2001/08/10 18:57:32 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -1027,17 +1027,10 @@ heap_get_latest_tid(Relation relation, ...@@ -1027,17 +1027,10 @@ heap_get_latest_tid(Relation relation,
} }
/* ---------------- /* ----------------
* heap_insert - insert tuple * heap_insert - insert tuple into a heap
* *
* The assignment of t_min (and thus the others) should be * The assignment of t_min (and thus the others) should be
* removed eventually. * removed eventually.
*
* Currently places the tuple onto the last page. If there is no room,
* it is placed on new pages. (Heap relations)
* Note that concurrent inserts during a scan will probably have
* unexpected results, though this will be fixed eventually.
*
* Fix to work with indexes.
* ---------------- * ----------------
*/ */
Oid Oid
...@@ -1049,6 +1042,8 @@ heap_insert(Relation relation, HeapTuple tup) ...@@ -1049,6 +1042,8 @@ heap_insert(Relation relation, HeapTuple tup)
IncrHeapAccessStat(local_insert); IncrHeapAccessStat(local_insert);
IncrHeapAccessStat(global_insert); IncrHeapAccessStat(global_insert);
if (relation->rd_rel->relhasoids)
{
/* /*
* If the object id of this tuple has already been assigned, trust the * If the object id of this tuple has already been assigned, trust the
* caller. There are a couple of ways this can happen. At initial db * caller. There are a couple of ways this can happen. At initial db
...@@ -1061,6 +1056,7 @@ heap_insert(Relation relation, HeapTuple tup) ...@@ -1061,6 +1056,7 @@ heap_insert(Relation relation, HeapTuple tup)
tup->t_data->t_oid = newoid(); tup->t_data->t_oid = newoid();
else else
CheckMaxObjectId(tup->t_data->t_oid); CheckMaxObjectId(tup->t_data->t_oid);
}
TransactionIdStore(GetCurrentTransactionId(), &(tup->t_data->t_xmin)); TransactionIdStore(GetCurrentTransactionId(), &(tup->t_data->t_xmin));
tup->t_data->t_cmin = GetCurrentCommandId(); tup->t_data->t_cmin = GetCurrentCommandId();
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.23 2001/06/22 19:16:20 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.24 2001/08/10 18:57:33 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -45,7 +45,7 @@ static void toast_delete(Relation rel, HeapTuple oldtup); ...@@ -45,7 +45,7 @@ static void toast_delete(Relation rel, HeapTuple oldtup);
static void toast_delete_datum(Relation rel, Datum value); static void toast_delete_datum(Relation rel, Datum value);
static void toast_insert_or_update(Relation rel, HeapTuple newtup, static void toast_insert_or_update(Relation rel, HeapTuple newtup,
HeapTuple oldtup); HeapTuple oldtup);
static Datum toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value); static Datum toast_save_datum(Relation rel, Datum value);
static varattrib *toast_fetch_datum(varattrib *attr); static varattrib *toast_fetch_datum(varattrib *attr);
...@@ -319,10 +319,10 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup) ...@@ -319,10 +319,10 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
VARATT_IS_EXTERNAL(old_value)) VARATT_IS_EXTERNAL(old_value))
{ {
if (new_isnull || !VARATT_IS_EXTERNAL(new_value) || if (new_isnull || !VARATT_IS_EXTERNAL(new_value) ||
old_value->va_content.va_external.va_rowid != old_value->va_content.va_external.va_valueid !=
new_value->va_content.va_external.va_rowid || new_value->va_content.va_external.va_valueid ||
old_value->va_content.va_external.va_attno != old_value->va_content.va_external.va_toastrelid !=
new_value->va_content.va_external.va_attno) new_value->va_content.va_external.va_toastrelid)
{ {
/* /*
...@@ -524,10 +524,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup) ...@@ -524,10 +524,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
i = biggest_attno; i = biggest_attno;
old_value = toast_values[i]; old_value = toast_values[i];
toast_action[i] = 'p'; toast_action[i] = 'p';
toast_values[i] = toast_save_datum(rel, toast_values[i] = toast_save_datum(rel, toast_values[i]);
newtup->t_data->t_oid,
i + 1,
toast_values[i]);
if (toast_free[i]) if (toast_free[i])
pfree(DatumGetPointer(old_value)); pfree(DatumGetPointer(old_value));
...@@ -639,10 +636,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup) ...@@ -639,10 +636,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
i = biggest_attno; i = biggest_attno;
old_value = toast_values[i]; old_value = toast_values[i];
toast_action[i] = 'p'; toast_action[i] = 'p';
toast_values[i] = toast_save_datum(rel, toast_values[i] = toast_save_datum(rel, toast_values[i]);
newtup->t_data->t_oid,
i + 1,
toast_values[i]);
if (toast_free[i]) if (toast_free[i])
pfree(DatumGetPointer(old_value)); pfree(DatumGetPointer(old_value));
...@@ -772,7 +766,7 @@ toast_compress_datum(Datum value) ...@@ -772,7 +766,7 @@ toast_compress_datum(Datum value)
* ---------- * ----------
*/ */
static Datum static Datum
toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value) toast_save_datum(Relation rel, Datum value)
{ {
Relation toastrel; Relation toastrel;
Relation toastidx; Relation toastidx;
...@@ -811,10 +805,6 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value) ...@@ -811,10 +805,6 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
result->va_content.va_external.va_valueid = newoid(); result->va_content.va_external.va_valueid = newoid();
result->va_content.va_external.va_toastrelid = result->va_content.va_external.va_toastrelid =
rel->rd_rel->reltoastrelid; rel->rd_rel->reltoastrelid;
result->va_content.va_external.va_toastidxid =
rel->rd_rel->reltoastidxid;
result->va_content.va_external.va_rowid = mainoid;
result->va_content.va_external.va_attno = attno;
/* /*
* Initialize constant parts of the tuple data * Initialize constant parts of the tuple data
...@@ -836,21 +826,20 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value) ...@@ -836,21 +826,20 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
*/ */
toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock); toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
toasttupDesc = toastrel->rd_att; toasttupDesc = toastrel->rd_att;
toastidx = index_open(rel->rd_rel->reltoastidxid); toastidx = index_open(toastrel->rd_rel->reltoastidxid);
/* /*
* Split up the item into chunks * Split up the item into chunks
*/ */
while (data_todo > 0) while (data_todo > 0)
{ {
/* /*
* Calculate the size of this chunk * Calculate the size of this chunk
*/ */
chunk_size = Min(TOAST_MAX_CHUNK_SIZE, data_todo); chunk_size = Min(TOAST_MAX_CHUNK_SIZE, data_todo);
/* /*
* Build a tuple * Build a tuple and store it
*/ */
t_values[1] = Int32GetDatum(chunk_seq++); t_values[1] = Int32GetDatum(chunk_seq++);
VARATT_SIZEP(&chunk_data) = chunk_size + VARHDRSZ; VARATT_SIZEP(&chunk_data) = chunk_size + VARHDRSZ;
...@@ -859,10 +848,16 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value) ...@@ -859,10 +848,16 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
if (!HeapTupleIsValid(toasttup)) if (!HeapTupleIsValid(toasttup))
elog(ERROR, "Failed to build TOAST tuple"); elog(ERROR, "Failed to build TOAST tuple");
heap_insert(toastrel, toasttup);
/* /*
* Store it and create the index entry * Create the index entry. We cheat a little here by not using
* FormIndexDatum: this relies on the knowledge that the index
* columns are the same as the initial columns of the table.
*
* Note also that there had better not be any user-created index
* on the TOAST table, since we don't bother to update anything else.
*/ */
heap_insert(toastrel, toasttup);
idxres = index_insert(toastidx, t_values, t_nulls, idxres = index_insert(toastidx, t_values, t_nulls,
&(toasttup->t_self), &(toasttup->t_self),
toastrel); toastrel);
...@@ -872,8 +867,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value) ...@@ -872,8 +867,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
/* /*
* Free memory * Free memory
*/ */
heap_freetuple(toasttup);
pfree(idxres); pfree(idxres);
heap_freetuple(toasttup);
/* /*
* Move on to next chunk * Move on to next chunk
...@@ -918,10 +913,11 @@ toast_delete_datum(Relation rel, Datum value) ...@@ -918,10 +913,11 @@ toast_delete_datum(Relation rel, Datum value)
*/ */
toastrel = heap_open(attr->va_content.va_external.va_toastrelid, toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
RowExclusiveLock); RowExclusiveLock);
toastidx = index_open(attr->va_content.va_external.va_toastidxid); toastidx = index_open(toastrel->rd_rel->reltoastidxid);
/* /*
* Setup a scan key to fetch from the index by va_valueid * Setup a scan key to fetch from the index by va_valueid
* (we don't particularly care whether we see them in sequence or not)
*/ */
ScanKeyEntryInitialize(&toastkey, ScanKeyEntryInitialize(&toastkey,
(bits16) 0, (bits16) 0,
...@@ -930,7 +926,7 @@ toast_delete_datum(Relation rel, Datum value) ...@@ -930,7 +926,7 @@ toast_delete_datum(Relation rel, Datum value)
ObjectIdGetDatum(attr->va_content.va_external.va_valueid)); ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
/* /*
* Read the chunks by index * Find the chunks by index
*/ */
toastscan = index_beginscan(toastidx, false, 1, &toastkey); toastscan = index_beginscan(toastidx, false, 1, &toastkey);
while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL) while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
...@@ -1009,7 +1005,7 @@ toast_fetch_datum(varattrib *attr) ...@@ -1009,7 +1005,7 @@ toast_fetch_datum(varattrib *attr)
toastrel = heap_open(attr->va_content.va_external.va_toastrelid, toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
AccessShareLock); AccessShareLock);
toasttupDesc = toastrel->rd_att; toasttupDesc = toastrel->rd_att;
toastidx = index_open(attr->va_content.va_external.va_toastidxid); toastidx = index_open(toastrel->rd_rel->reltoastidxid);
/* /*
* Setup a scan key to fetch from the index by va_valueid * Setup a scan key to fetch from the index by va_valueid
...@@ -1049,25 +1045,25 @@ toast_fetch_datum(varattrib *attr) ...@@ -1049,25 +1045,25 @@ toast_fetch_datum(varattrib *attr)
* Some checks on the data we've found * Some checks on the data we've found
*/ */
if (residx < 0 || residx >= numchunks) if (residx < 0 || residx >= numchunks)
elog(ERROR, "unexpected chunk number %d for toast value %d", elog(ERROR, "unexpected chunk number %d for toast value %u",
residx, residx,
attr->va_content.va_external.va_valueid); attr->va_content.va_external.va_valueid);
if (residx < numchunks - 1) if (residx < numchunks - 1)
{ {
if (chunksize != TOAST_MAX_CHUNK_SIZE) if (chunksize != TOAST_MAX_CHUNK_SIZE)
elog(ERROR, "unexpected chunk size %d in chunk %d for toast value %d", elog(ERROR, "unexpected chunk size %d in chunk %d for toast value %u",
chunksize, residx, chunksize, residx,
attr->va_content.va_external.va_valueid); attr->va_content.va_external.va_valueid);
} }
else else
{ {
if ((residx * TOAST_MAX_CHUNK_SIZE + chunksize) != ressize) if ((residx * TOAST_MAX_CHUNK_SIZE + chunksize) != ressize)
elog(ERROR, "unexpected chunk size %d in chunk %d for toast value %d", elog(ERROR, "unexpected chunk size %d in chunk %d for toast value %u",
chunksize, residx, chunksize, residx,
attr->va_content.va_external.va_valueid); attr->va_content.va_external.va_valueid);
} }
if (chunks_found[residx]++ > 0) if (chunks_found[residx]++ > 0)
elog(ERROR, "chunk %d for toast value %d appears multiple times", elog(ERROR, "chunk %d for toast value %u appears multiple times",
residx, residx,
attr->va_content.va_external.va_valueid); attr->va_content.va_external.va_valueid);
...@@ -1085,7 +1081,7 @@ toast_fetch_datum(varattrib *attr) ...@@ -1085,7 +1081,7 @@ toast_fetch_datum(varattrib *attr)
* Final checks that we successfully fetched the datum * Final checks that we successfully fetched the datum
*/ */
if (memcmp(chunks_found, chunks_expected, numchunks) != 0) if (memcmp(chunks_found, chunks_expected, numchunks) != 0)
elog(ERROR, "not all toast chunks found for value %d", elog(ERROR, "not all toast chunks found for value %u",
attr->va_content.va_external.va_valueid); attr->va_content.va_external.va_valueid);
pfree(chunks_expected); pfree(chunks_expected);
pfree(chunks_found); pfree(chunks_found);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (c) 2000, PostgreSQL Global Development Group * Copyright (c) 2000, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.42 2001/07/16 22:43:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.43 2001/08/10 18:57:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -105,11 +105,26 @@ ReadNewTransactionId(TransactionId *xid) ...@@ -105,11 +105,26 @@ ReadNewTransactionId(TransactionId *xid)
static Oid lastSeenOid = InvalidOid; static Oid lastSeenOid = InvalidOid;
void Oid
GetNewObjectId(Oid *oid_return) GetNewObjectId(void)
{ {
Oid result;
SpinAcquire(OidGenLockId); SpinAcquire(OidGenLockId);
/*
* Check for wraparound of the OID counter. We *must* not return 0
* (InvalidOid); and as long as we have to check that, it seems a good
* idea to skip over everything below BootstrapObjectIdData too. (This
* basically just reduces the odds of OID collision right after a wrap
* occurs.) Note we are relying on unsigned comparison here.
*/
if (ShmemVariableCache->nextOid < ((Oid) BootstrapObjectIdData))
{
ShmemVariableCache->nextOid = BootstrapObjectIdData;
ShmemVariableCache->oidCount = 0;
}
/* If we run out of logged for use oids then we must log more */ /* If we run out of logged for use oids then we must log more */
if (ShmemVariableCache->oidCount == 0) if (ShmemVariableCache->oidCount == 0)
{ {
...@@ -117,13 +132,16 @@ GetNewObjectId(Oid *oid_return) ...@@ -117,13 +132,16 @@ GetNewObjectId(Oid *oid_return)
ShmemVariableCache->oidCount = VAR_OID_PREFETCH; ShmemVariableCache->oidCount = VAR_OID_PREFETCH;
} }
if (PointerIsValid(oid_return)) result = ShmemVariableCache->nextOid;
lastSeenOid = (*oid_return) = ShmemVariableCache->nextOid;
(ShmemVariableCache->nextOid)++; (ShmemVariableCache->nextOid)++;
(ShmemVariableCache->oidCount)--; (ShmemVariableCache->oidCount)--;
SpinRelease(OidGenLockId); SpinRelease(OidGenLockId);
lastSeenOid = result;
return result;
} }
void void
...@@ -159,8 +177,8 @@ CheckMaxObjectId(Oid assigned_oid) ...@@ -159,8 +177,8 @@ CheckMaxObjectId(Oid assigned_oid)
*/ */
XLogPutNextOid(assigned_oid + VAR_OID_PREFETCH); XLogPutNextOid(assigned_oid + VAR_OID_PREFETCH);
ShmemVariableCache->oidCount = VAR_OID_PREFETCH - 1;
ShmemVariableCache->nextOid = assigned_oid + 1; ShmemVariableCache->nextOid = assigned_oid + 1;
ShmemVariableCache->oidCount = VAR_OID_PREFETCH - 1;
SpinRelease(OidGenLockId); SpinRelease(OidGenLockId);
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.72 2001/07/22 22:01:04 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.73 2001/08/10 18:57:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2510,8 +2510,6 @@ StartupXLOG(void) ...@@ -2510,8 +2510,6 @@ StartupXLOG(void)
checkPoint.nextXid, checkPoint.nextOid); checkPoint.nextXid, checkPoint.nextOid);
if (checkPoint.nextXid < FirstTransactionId) if (checkPoint.nextXid < FirstTransactionId)
elog(STOP, "invalid next transaction id"); elog(STOP, "invalid next transaction id");
if (checkPoint.nextOid < BootstrapObjectIdData)
elog(STOP, "invalid next oid");
ShmemVariableCache->nextXid = checkPoint.nextXid; ShmemVariableCache->nextXid = checkPoint.nextXid;
ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->nextOid = checkPoint.nextOid;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.36 2001/05/12 01:48:49 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.37 2001/08/10 18:57:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -75,7 +75,6 @@ do_end() ...@@ -75,7 +75,6 @@ do_end()
int num_columns_read = 0; int num_columns_read = 0;
static Oid objectid;
%} %}
...@@ -91,7 +90,7 @@ static Oid objectid; ...@@ -91,7 +90,7 @@ static Oid objectid;
%type <list> boot_index_params %type <list> boot_index_params
%type <ielem> boot_index_param %type <ielem> boot_index_param
%type <ival> boot_const boot_ident %type <ival> boot_const boot_ident
%type <ival> optbootstrap boot_tuple boot_tuplelist %type <ival> optbootstrap optwithoutoids boot_tuple boot_tuplelist
%type <oidval> optoideq %type <oidval> optoideq
%token <ival> CONST ID %token <ival> CONST ID
...@@ -99,7 +98,7 @@ static Oid objectid; ...@@ -99,7 +98,7 @@ static Oid objectid;
%token STRING XDEFINE %token STRING XDEFINE
%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE %token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE
%token COMMA EQUALS LPAREN RPAREN %token COMMA EQUALS LPAREN RPAREN
%token OBJ_ID XBOOTSTRAP NULLVAL %token OBJ_ID XBOOTSTRAP XWITHOUT_OIDS NULLVAL
%start TopLevel %start TopLevel
%nonassoc low %nonassoc low
...@@ -152,7 +151,7 @@ Boot_CloseStmt: ...@@ -152,7 +151,7 @@ Boot_CloseStmt:
; ;
Boot_CreateStmt: Boot_CreateStmt:
XCREATE optbootstrap boot_ident LPAREN XCREATE optbootstrap optwithoutoids boot_ident LPAREN
{ {
do_start(); do_start();
numattr = 0; numattr = 0;
...@@ -160,10 +159,10 @@ Boot_CreateStmt: ...@@ -160,10 +159,10 @@ Boot_CreateStmt:
{ {
if ($2) if ($2)
elog(DEBUG, "creating bootstrap relation %s...", elog(DEBUG, "creating bootstrap relation %s...",
LexIDStr($3)); LexIDStr($4));
else else
elog(DEBUG, "creating relation %s...", elog(DEBUG, "creating relation %s...",
LexIDStr($3)); LexIDStr($4));
} }
} }
boot_typelist boot_typelist
...@@ -185,9 +184,10 @@ Boot_CreateStmt: ...@@ -185,9 +184,10 @@ Boot_CreateStmt:
closerel(NULL); closerel(NULL);
} }
tupdesc = CreateTupleDesc(numattr,attrtypes); tupdesc = CreateTupleDesc(numattr, attrtypes);
reldesc = heap_create(LexIDStr($3), tupdesc, reldesc = heap_create(LexIDStr($4), tupdesc,
false, true, true); false, true, true);
reldesc->rd_rel->relhasoids = ! ($3);
if (DebugMode) if (DebugMode)
elog(DEBUG, "bootstrap relation created"); elog(DEBUG, "bootstrap relation created");
} }
...@@ -197,9 +197,10 @@ Boot_CreateStmt: ...@@ -197,9 +197,10 @@ Boot_CreateStmt:
TupleDesc tupdesc; TupleDesc tupdesc;
tupdesc = CreateTupleDesc(numattr,attrtypes); tupdesc = CreateTupleDesc(numattr,attrtypes);
id = heap_create_with_catalog(LexIDStr($3), id = heap_create_with_catalog(LexIDStr($4),
tupdesc, tupdesc,
RELKIND_RELATION, RELKIND_RELATION,
! ($3),
false, false,
true); true);
if (DebugMode) if (DebugMode)
...@@ -232,8 +233,7 @@ Boot_InsertStmt: ...@@ -232,8 +233,7 @@ Boot_InsertStmt:
elog(ERROR, "relation not open"); elog(ERROR, "relation not open");
err_out(); err_out();
} }
objectid = $2; InsertOneTuple($2);
InsertOneTuple(objectid);
do_end(); do_end();
} }
; ;
...@@ -287,6 +287,11 @@ optbootstrap: ...@@ -287,6 +287,11 @@ optbootstrap:
| { $$ = 0; } | { $$ = 0; }
; ;
optwithoutoids:
XWITHOUT_OIDS { $$ = 1; }
| { $$ = 0; }
;
boot_typelist: boot_typelist:
boot_type_thing boot_type_thing
| boot_typelist COMMA boot_type_thing | boot_typelist COMMA boot_type_thing
...@@ -303,7 +308,7 @@ boot_type_thing: ...@@ -303,7 +308,7 @@ boot_type_thing:
optoideq: optoideq:
OBJ_ID EQUALS boot_ident { $$ = atol(LexIDStr($3)); } OBJ_ID EQUALS boot_ident { $$ = atol(LexIDStr($3)); }
| { $$ = newoid(); } | { $$ = (Oid) 0; }
; ;
boot_tuplelist: boot_tuplelist:
...@@ -313,8 +318,10 @@ boot_tuplelist: ...@@ -313,8 +318,10 @@ boot_tuplelist:
; ;
boot_tuple: boot_tuple:
boot_ident {InsertOneValue(objectid, LexIDStr($1), num_columns_read++); } boot_ident
| boot_const {InsertOneValue(objectid, LexIDStr($1), num_columns_read++); } { InsertOneValue(LexIDStr($1), num_columns_read++); }
| boot_const
{ InsertOneValue(LexIDStr($1), num_columns_read++); }
| NULLVAL | NULLVAL
{ InsertOneNull(num_columns_read++); } { InsertOneNull(num_columns_read++); }
; ;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.20 2001/05/12 01:48:49 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.21 2001/08/10 18:57:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -94,6 +94,8 @@ insert { return(INSERT_TUPLE); } ...@@ -94,6 +94,8 @@ insert { return(INSERT_TUPLE); }
"index" { return(INDEX); } "index" { return(INDEX); }
"on" { return(ON); } "on" { return(ON); }
"using" { return(USING); } "using" { return(USING); }
"without_oids" { return(XWITHOUT_OIDS); }
{arrayid} { {arrayid} {
yylval.ival = EnterString(MapArrayTypeName((char*)yytext)); yylval.ival = EnterString(MapArrayTypeName((char*)yytext));
return(ID); return(ID);
......
...@@ -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
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.113 2001/08/04 00:14:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.114 2001/08/10 18:57:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -627,7 +627,9 @@ DefineAttr(char *name, char *type, int attnum) ...@@ -627,7 +627,9 @@ DefineAttr(char *name, char *type, int attnum)
/* ---------------- /* ----------------
* InsertOneTuple * InsertOneTuple
* assumes that 'oid' will not be zero. *
* If objectid is not zero, it is a specific OID to assign to the tuple.
* Otherwise, an OID will be assigned (if necessary) by heap_insert.
* ---------------- * ----------------
*/ */
void void
...@@ -635,7 +637,6 @@ InsertOneTuple(Oid objectid) ...@@ -635,7 +637,6 @@ InsertOneTuple(Oid objectid)
{ {
HeapTuple tuple; HeapTuple tuple;
TupleDesc tupDesc; TupleDesc tupDesc;
int i; int i;
if (DebugMode) if (DebugMode)
...@@ -664,7 +665,7 @@ InsertOneTuple(Oid objectid) ...@@ -664,7 +665,7 @@ InsertOneTuple(Oid objectid)
* ---------------- * ----------------
*/ */
void void
InsertOneValue(Oid objectid, char *value, int i) InsertOneValue(char *value, int i)
{ {
int typeindex; int typeindex;
char *prt; char *prt;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.42 2001/05/30 20:52:32 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.43 2001/08/10 18:57:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -124,24 +124,13 @@ IsSharedSystemRelationName(const char *relname) ...@@ -124,24 +124,13 @@ IsSharedSystemRelationName(const char *relname)
* newoid - returns a unique identifier across all catalogs. * newoid - returns a unique identifier across all catalogs.
* *
* Object Id allocation is now done by GetNewObjectID in * Object Id allocation is now done by GetNewObjectID in
* access/transam/varsup.c. oids are now allocated correctly. * access/transam/varsup.
* *
* old comments: * This code probably needs to change to generate OIDs separately
* This needs to change soon, it fails if there are too many more * for each table.
* than one call per second when postgres restarts after it dies.
*
* The distribution of OID's should be done by the POSTMASTER.
* Also there needs to be a facility to preallocate OID's. Ie.,
* for a block of OID's to be declared as invalid ones to allow
* user programs to use them for temporary object identifiers.
*/ */
Oid Oid
newoid(void) newoid(void)
{ {
Oid lastoid; return GetNewObjectId();
GetNewObjectId(&lastoid);
if (!OidIsValid(lastoid))
elog(ERROR, "newoid: GetNewObjectId returns invalid oid");
return lastoid;
} }
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# #
# IDENTIFICATION # IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.20 2001/05/07 00:43:16 tgl Exp $ # $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.21 2001/08/10 18:57:33 tgl Exp $
# #
# NOTES # NOTES
# non-essential whitespace is removed from the generated file. # non-essential whitespace is removed from the generated file.
...@@ -136,6 +136,15 @@ for dir in $INCLUDE_DIRS; do ...@@ -136,6 +136,15 @@ for dir in $INCLUDE_DIRS; do
fi fi
done done
# Get FirstGenBKIObjectId from access/transam.h
for dir in $INCLUDE_DIRS; do
if [ -f "$dir/access/transam.h" ]; then
BKIOBJECTID=`grep '#define[ ]*FirstGenBKIObjectId' $dir/access/transam.h | $AWK '{ print $3 }'`
break
fi
done
export BKIOBJECTID
# NOTE: we assume here that FUNC_MAX_ARGS has the same value as INDEX_MAX_KEYS, # NOTE: we assume here that FUNC_MAX_ARGS has the same value as INDEX_MAX_KEYS,
# and don't read it separately from config.h. This is OK because both of them # and don't read it separately from config.h. This is OK because both of them
# must be equal to the length of oidvector. # must be equal to the length of oidvector.
...@@ -184,16 +193,21 @@ sed -e "s/;[ ]*$//g" \ ...@@ -184,16 +193,21 @@ sed -e "s/;[ ]*$//g" \
# nc is the number of catalogs # nc is the number of catalogs
# inside is a variable set to 1 when we are scanning the # inside is a variable set to 1 when we are scanning the
# contents of a catalog definition. # contents of a catalog definition.
# inserting_data is a flag indicating when we are processing DATA lines. # reln_open is a flag indicating when we are processing DATA lines.
# (i.e. have a relation open and need to close it) # (i.e. have a relation open and need to close it)
# nextbkioid is the next OID available for automatic assignment.
# oid is the most recently seen or assigned oid.
# ---------------- # ----------------
BEGIN { BEGIN {
inside = 0; inside = 0;
raw = 0; raw = 0;
bootstrap = 0; bootstrap = "";
without_oids = "";
nc = 0; nc = 0;
reln_open = 0; reln_open = 0;
comment_level = 0; comment_level = 0;
nextbkioid = ENVIRON["BKIOBJECTID"];
oid = 0;
} }
# ---------------- # ----------------
...@@ -217,23 +231,26 @@ comment_level > 0 { next; } ...@@ -217,23 +231,26 @@ comment_level > 0 { next; }
raw == 1 { print; next; } raw == 1 { print; next; }
# ---------------- # ----------------
# DATA() statements should get passed right through after # DATA() statements are basically passed right through after
# stripping off the DATA( and the ) on the end. # stripping off the DATA( and the ) on the end. However,
# if we see "OID = 0" then we should assign an oid from nextbkioid.
# Remember any explicit or assigned OID for use by DESCR().
# ---------------- # ----------------
/^DATA\(/ { /^DATA\(/ {
data = substr($0, 6, length($0) - 6); data = substr($0, 6, length($0) - 6);
print data;
nf = 1;
oid = 0; oid = 0;
while (nf <= NF-3) nf = split(data, datafields);
if (nf >= 4 && datafields[1] == "insert" && datafields[2] == "OID" && datafields[3] == "=")
{ {
if ($nf == "OID" && $(nf+1) == "=") oid = datafields[4];
if (oid == 0)
{ {
oid = $(nf+2); oid = nextbkioid;
break; nextbkioid++;
sub("OID *= *0", "OID = " oid, data);
} }
nf++;
} }
print data;
next; next;
} }
...@@ -242,7 +259,7 @@ raw == 1 { print; next; } ...@@ -242,7 +259,7 @@ raw == 1 { print; next; }
{ {
data = substr($0, 8, length($0) - 9); data = substr($0, 8, length($0) - 9);
if (data != "") if (data != "")
printf "%d %s\n", oid, data >>descriptionfile; printf "%d\t%s\t0\t%s\n", oid, catalog, data >>descriptionfile;
} }
next; next;
} }
...@@ -291,13 +308,16 @@ raw == 1 { print; next; } ...@@ -291,13 +308,16 @@ raw == 1 { print; next; }
} }
# ---- # ----
# get the name of the new catalog # get the name and properties of the new catalog
# ---- # ----
pos = index($1,")"); pos = index($1,")");
catalog = substr($1,9,pos-9); catalog = substr($1,9,pos-9);
if ($0 ~ /BOOTSTRAP/) { if ($0 ~ /BOOTSTRAP/) {
bootstrap = 1; bootstrap = "bootstrap ";
}
if ($0 ~ /BKI_WITHOUT_OIDS/) {
without_oids = "without_oids ";
} }
i = 1; i = 1;
...@@ -323,11 +343,7 @@ inside == 1 { ...@@ -323,11 +343,7 @@ inside == 1 {
# if this is the last line, then output the bki catalog stuff. # if this is the last line, then output the bki catalog stuff.
# ---- # ----
if ($1 ~ /}/) { if ($1 ~ /}/) {
if (bootstrap) { print "create " bootstrap without_oids catalog;
print "create bootstrap " catalog;
} else {
print "create " catalog;
}
print "\t("; print "\t(";
for (j=1; j<i-1; j++) { for (j=1; j<i-1; j++) {
...@@ -336,14 +352,15 @@ inside == 1 { ...@@ -336,14 +352,15 @@ inside == 1 {
print "\t " attname[ j ] " = " atttype[ j ] ; print "\t " attname[ j ] " = " atttype[ j ] ;
print "\t)"; print "\t)";
if (! bootstrap) { if (bootstrap == "") {
print "open " catalog; print "open " catalog;
} }
i = 1; i = 1;
reln_open = 1; reln_open = 1;
inside = 0; inside = 0;
bootstrap = 0; bootstrap = "";
without_oids = "";
next; next;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.173 2001/08/10 15:49:39 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.174 2001/08/10 18:57:33 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -64,8 +64,10 @@ ...@@ -64,8 +64,10 @@
static void AddNewRelationTuple(Relation pg_class_desc, static void AddNewRelationTuple(Relation pg_class_desc,
Relation new_rel_desc, Oid new_rel_oid, Oid new_type_oid, Relation new_rel_desc,
int natts, char relkind, char *temp_relname); Oid new_rel_oid, Oid new_type_oid,
char relkind, bool relhasoids,
char *temp_relname);
static void DeleteAttributeTuples(Relation rel); static void DeleteAttributeTuples(Relation rel);
static void DeleteRelationTuple(Relation rel); static void DeleteRelationTuple(Relation rel);
static void DeleteTypeTuple(Relation rel); static void DeleteTypeTuple(Relation rel);
...@@ -151,11 +153,14 @@ static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7}; ...@@ -151,11 +153,14 @@ static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
* This function returns a Form_pg_attribute pointer for a system attribute. * This function returns a Form_pg_attribute pointer for a system attribute.
*/ */
Form_pg_attribute Form_pg_attribute
SystemAttributeDefinition(AttrNumber attno) SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
{ {
if (attno >= 0 || attno < - (int) lengthof(SysAtt)) if (attno >= 0 || attno < - (int) lengthof(SysAtt))
elog(ERROR, "SystemAttributeDefinition: invalid attribute number %d", elog(ERROR, "SystemAttributeDefinition: invalid attribute number %d",
attno); attno);
if (attno == ObjectIdAttributeNumber && !relhasoids)
elog(ERROR, "SystemAttributeDefinition: invalid attribute number %d",
attno);
return SysAtt[-attno - 1]; return SysAtt[-attno - 1];
} }
...@@ -167,9 +172,8 @@ SystemAttributeDefinition(AttrNumber attno) ...@@ -167,9 +172,8 @@ SystemAttributeDefinition(AttrNumber attno)
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* heap_create - Create an uncataloged heap relation * heap_create - Create an uncataloged heap relation
* *
* Fields relpages, reltuples, reltuples, relkeys, relhistory, * rel->rd_rel is initialized by RelationBuildLocalRelation,
* relisindexed, and relkind of rel->rd_rel are initialized * and is mostly zeroes at return.
* to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1.
* *
* Remove the system relation specific code to elsewhere eventually. * Remove the system relation specific code to elsewhere eventually.
* *
...@@ -337,7 +341,7 @@ heap_storage_create(Relation rel) ...@@ -337,7 +341,7 @@ heap_storage_create(Relation rel)
* -------------------------------- * --------------------------------
*/ */
static void static void
CheckAttributeNames(TupleDesc tupdesc) CheckAttributeNames(TupleDesc tupdesc, bool relhasoids)
{ {
int i; int i;
int j; int j;
...@@ -352,21 +356,20 @@ CheckAttributeNames(TupleDesc tupdesc) ...@@ -352,21 +356,20 @@ CheckAttributeNames(TupleDesc tupdesc)
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
{ {
for (j = 0; j < (int) lengthof(SysAtt); j++) for (j = 0; j < (int) lengthof(SysAtt); j++)
{
if (relhasoids || SysAtt[j]->attnum != ObjectIdAttributeNumber)
{ {
if (strcmp(NameStr(SysAtt[j]->attname), if (strcmp(NameStr(SysAtt[j]->attname),
NameStr(tupdesc->attrs[i]->attname)) == 0) NameStr(tupdesc->attrs[i]->attname)) == 0)
{
elog(ERROR, "name of column \"%s\" conflicts with an existing system column", elog(ERROR, "name of column \"%s\" conflicts with an existing system column",
NameStr(SysAtt[j]->attname)); NameStr(SysAtt[j]->attname));
} }
} }
if (tupdesc->attrs[i]->atttypid == UNKNOWNOID) if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
{
elog(NOTICE, "Attribute '%s' has an unknown type" elog(NOTICE, "Attribute '%s' has an unknown type"
"\n\tRelation created; continue", "\n\tProceeding with relation creation anyway",
NameStr(tupdesc->attrs[i]->attname)); NameStr(tupdesc->attrs[i]->attname));
} }
}
/* /*
* next check for repeated attribute names * next check for repeated attribute names
...@@ -377,12 +380,10 @@ CheckAttributeNames(TupleDesc tupdesc) ...@@ -377,12 +380,10 @@ CheckAttributeNames(TupleDesc tupdesc)
{ {
if (strcmp(NameStr(tupdesc->attrs[j]->attname), if (strcmp(NameStr(tupdesc->attrs[j]->attname),
NameStr(tupdesc->attrs[i]->attname)) == 0) NameStr(tupdesc->attrs[i]->attname)) == 0)
{
elog(ERROR, "column name \"%s\" is duplicated", elog(ERROR, "column name \"%s\" is duplicated",
NameStr(tupdesc->attrs[j]->attname)); NameStr(tupdesc->attrs[j]->attname));
} }
} }
}
} }
/* -------------------------------- /* --------------------------------
...@@ -461,7 +462,8 @@ RelnameFindRelid(const char *relname) ...@@ -461,7 +462,8 @@ RelnameFindRelid(const char *relname)
*/ */
static void static void
AddNewAttributeTuples(Oid new_rel_oid, AddNewAttributeTuples(Oid new_rel_oid,
TupleDesc tupdesc) TupleDesc tupdesc,
bool relhasoids)
{ {
Form_pg_attribute *dpp; Form_pg_attribute *dpp;
int i; int i;
...@@ -509,10 +511,12 @@ AddNewAttributeTuples(Oid new_rel_oid, ...@@ -509,10 +511,12 @@ AddNewAttributeTuples(Oid new_rel_oid,
} }
/* /*
* next we add the system attributes.. * next we add the system attributes. Skip OID if rel has no OIDs.
*/ */
dpp = SysAtt; dpp = SysAtt;
for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++) for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
{
if (relhasoids || (*dpp)->attnum != ObjectIdAttributeNumber)
{ {
Form_pg_attribute attStruct; Form_pg_attribute attStruct;
...@@ -533,6 +537,7 @@ AddNewAttributeTuples(Oid new_rel_oid, ...@@ -533,6 +537,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup); CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
heap_freetuple(tup); heap_freetuple(tup);
}
dpp++; dpp++;
} }
...@@ -557,8 +562,8 @@ AddNewRelationTuple(Relation pg_class_desc, ...@@ -557,8 +562,8 @@ AddNewRelationTuple(Relation pg_class_desc,
Relation new_rel_desc, Relation new_rel_desc,
Oid new_rel_oid, Oid new_rel_oid,
Oid new_type_oid, Oid new_type_oid,
int natts,
char relkind, char relkind,
bool relhasoids,
char *temp_relname) char *temp_relname)
{ {
Form_pg_class new_rel_reltup; Form_pg_class new_rel_reltup;
...@@ -610,7 +615,7 @@ AddNewRelationTuple(Relation pg_class_desc, ...@@ -610,7 +615,7 @@ AddNewRelationTuple(Relation pg_class_desc,
new_rel_reltup->relowner = GetUserId(); new_rel_reltup->relowner = GetUserId();
new_rel_reltup->reltype = new_type_oid; new_rel_reltup->reltype = new_type_oid;
new_rel_reltup->relkind = relkind; new_rel_reltup->relkind = relkind;
new_rel_reltup->relnatts = natts; new_rel_reltup->relhasoids = relhasoids;
/* ---------------- /* ----------------
* now form a tuple to add to pg_class * now form a tuple to add to pg_class
...@@ -697,6 +702,7 @@ Oid ...@@ -697,6 +702,7 @@ Oid
heap_create_with_catalog(char *relname, heap_create_with_catalog(char *relname,
TupleDesc tupdesc, TupleDesc tupdesc,
char relkind, char relkind,
bool relhasoids,
bool istemp, bool istemp,
bool allow_system_table_mods) bool allow_system_table_mods)
{ {
...@@ -704,18 +710,17 @@ heap_create_with_catalog(char *relname, ...@@ -704,18 +710,17 @@ heap_create_with_catalog(char *relname,
Relation new_rel_desc; Relation new_rel_desc;
Oid new_rel_oid; Oid new_rel_oid;
Oid new_type_oid; Oid new_type_oid;
int natts = tupdesc->natts;
char *temp_relname = NULL; char *temp_relname = NULL;
/* /*
* sanity checks * sanity checks
*/ */
Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode()); Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());
if (natts <= 0 || natts > MaxHeapAttributeNumber) if (tupdesc->natts <= 0 || tupdesc->natts > MaxHeapAttributeNumber)
elog(ERROR, "Number of columns is out of range (1 to %d)", elog(ERROR, "Number of columns is out of range (1 to %d)",
MaxHeapAttributeNumber); MaxHeapAttributeNumber);
CheckAttributeNames(tupdesc); CheckAttributeNames(tupdesc, relhasoids);
/* temp tables can mask non-temp tables */ /* temp tables can mask non-temp tables */
if ((!istemp && RelnameFindRelid(relname)) || if ((!istemp && RelnameFindRelid(relname)) ||
...@@ -763,8 +768,8 @@ heap_create_with_catalog(char *relname, ...@@ -763,8 +768,8 @@ heap_create_with_catalog(char *relname,
new_rel_desc, new_rel_desc,
new_rel_oid, new_rel_oid,
new_type_oid, new_type_oid,
natts,
relkind, relkind,
relhasoids,
temp_relname); temp_relname);
/* /*
...@@ -780,16 +785,10 @@ heap_create_with_catalog(char *relname, ...@@ -780,16 +785,10 @@ heap_create_with_catalog(char *relname,
* now add tuples to pg_attribute for the attributes in our new * now add tuples to pg_attribute for the attributes in our new
* relation. * relation.
*/ */
AddNewAttributeTuples(new_rel_oid, tupdesc); AddNewAttributeTuples(new_rel_oid, tupdesc, relhasoids);
StoreConstraints(new_rel_desc); StoreConstraints(new_rel_desc);
if (istemp)
{
pfree(relname);
pfree(temp_relname);
}
/* /*
* We create the disk file for this relation here * We create the disk file for this relation here
*/ */
...@@ -799,12 +798,16 @@ heap_create_with_catalog(char *relname, ...@@ -799,12 +798,16 @@ heap_create_with_catalog(char *relname,
/* /*
* ok, the relation has been cataloged, so close our relations and * ok, the relation has been cataloged, so close our relations and
* return the oid of the newly created relation. * return the oid of the newly created relation.
*
* SOMEDAY: fill the STATISTIC relation properly.
*/ */
heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
heap_close(pg_class_desc, RowExclusiveLock); heap_close(pg_class_desc, RowExclusiveLock);
if (istemp)
{
pfree(relname);
pfree(temp_relname);
}
return new_rel_oid; return new_rel_oid;
} }
...@@ -1120,9 +1123,6 @@ DeleteAttributeTuples(Relation rel) ...@@ -1120,9 +1123,6 @@ DeleteAttributeTuples(Relation rel)
0, 0); 0, 0);
if (HeapTupleIsValid(tup)) if (HeapTupleIsValid(tup))
{ {
/*** Delete any comments associated with this attribute ***/
DeleteComments(tup->t_data->t_oid);
simple_heap_delete(pg_attribute_desc, &tup->t_self); simple_heap_delete(pg_attribute_desc, &tup->t_self);
heap_freetuple(tup); heap_freetuple(tup);
} }
...@@ -1333,7 +1333,7 @@ heap_drop_with_catalog(const char *relname, ...@@ -1333,7 +1333,7 @@ heap_drop_with_catalog(const char *relname,
/* /*
* delete comments, statistics, and constraints * delete comments, statistics, and constraints
*/ */
DeleteComments(RelationGetRelid(rel)); DeleteComments(rid, RelOid_pg_class);
RemoveStatistics(rel); RemoveStatistics(rel);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.158 2001/08/10 15:49:39 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.159 2001/08/10 18:57:33 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -229,7 +229,8 @@ ConstructTupleDescriptor(Relation heapRelation, ...@@ -229,7 +229,8 @@ ConstructTupleDescriptor(Relation heapRelation,
/* /*
* here we are indexing on a system attribute (-1...-n) * here we are indexing on a system attribute (-1...-n)
*/ */
from = SystemAttributeDefinition(atnum); from = SystemAttributeDefinition(atnum,
heapRelation->rd_rel->relhasoids);
} }
else else
{ {
...@@ -355,6 +356,7 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid) ...@@ -355,6 +356,7 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid)
indexRelation->rd_rel->relisshared = indexRelation->rd_rel->relisshared =
IsSharedSystemRelationName(RelationGetPhysicalRelationName(indexRelation)); IsSharedSystemRelationName(RelationGetPhysicalRelationName(indexRelation));
indexRelation->rd_rel->relkind = RELKIND_INDEX; indexRelation->rd_rel->relkind = RELKIND_INDEX;
indexRelation->rd_rel->relhasoids = false;
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
...@@ -659,9 +661,11 @@ InitIndexStrategy(int numatts, ...@@ -659,9 +661,11 @@ InitIndexStrategy(int numatts,
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* index_create * index_create
*
* Returns OID of the created index.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
void Oid
index_create(char *heapRelationName, index_create(char *heapRelationName,
char *indexRelationName, char *indexRelationName,
IndexInfo *indexInfo, IndexInfo *indexInfo,
...@@ -803,6 +807,8 @@ index_create(char *heapRelationName, ...@@ -803,6 +807,8 @@ index_create(char *heapRelationName,
} }
else else
index_build(heapRelation, indexRelation, indexInfo); index_build(heapRelation, indexRelation, indexInfo);
return indexoid;
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
...@@ -852,7 +858,7 @@ index_drop(Oid indexId) ...@@ -852,7 +858,7 @@ index_drop(Oid indexId)
/* /*
* fix DESCRIPTION relation * fix DESCRIPTION relation
*/ */
DeleteComments(indexId); DeleteComments(indexId, RelOid_pg_class);
/* /*
* fix RELATION relation * fix RELATION relation
...@@ -877,8 +883,11 @@ index_drop(Oid indexId) ...@@ -877,8 +883,11 @@ index_drop(Oid indexId)
* must send out a shared-cache-inval notice on the owning relation to * must send out a shared-cache-inval notice on the owning relation to
* ensure other backends update their relcache lists of indexes. So, * ensure other backends update their relcache lists of indexes. So,
* unconditionally do setRelhasindex(true). * unconditionally do setRelhasindex(true).
*
* Possible future improvement: skip the physical tuple update and
* just send out an invalidation message.
*/ */
setRelhasindex(heapId, true); setRelhasindex(heapId, true, false, InvalidOid);
heap_close(relationRelation, RowExclusiveLock); heap_close(relationRelation, RowExclusiveLock);
...@@ -1199,6 +1208,12 @@ IndexesAreActive(Oid relid, bool confirmCommitted) ...@@ -1199,6 +1208,12 @@ IndexesAreActive(Oid relid, bool confirmCommitted)
/* ---------------- /* ----------------
* set relhasindex of relation's pg_class entry * set relhasindex of relation's pg_class entry
* *
* If isprimary is TRUE, we are defining a primary index, so also set
* relhaspkey to TRUE. Otherwise, leave relhaspkey alone.
*
* If reltoastidxid is not InvalidOid, also set reltoastidxid to that value.
* This is only used for TOAST relations.
*
* NOTE: an important side-effect of this operation is that an SI invalidation * NOTE: an important side-effect of this operation is that an SI invalidation
* message is sent out to all backends --- including me --- causing relcache * message is sent out to all backends --- including me --- causing relcache
* entries to be flushed or updated with the new hasindex data. * entries to be flushed or updated with the new hasindex data.
...@@ -1208,10 +1223,11 @@ IndexesAreActive(Oid relid, bool confirmCommitted) ...@@ -1208,10 +1223,11 @@ IndexesAreActive(Oid relid, bool confirmCommitted)
* ---------------- * ----------------
*/ */
void void
setRelhasindex(Oid relid, bool hasindex) setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
{ {
Relation pg_class; Relation pg_class;
HeapTuple tuple; HeapTuple tuple;
Form_pg_class classtuple;
HeapScanDesc pg_class_scan = NULL; HeapScanDesc pg_class_scan = NULL;
/* /*
...@@ -1219,7 +1235,8 @@ setRelhasindex(Oid relid, bool hasindex) ...@@ -1219,7 +1235,8 @@ setRelhasindex(Oid relid, bool hasindex)
*/ */
pg_class = heap_openr(RelationRelationName, RowExclusiveLock); pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
if (!IsIgnoringSystemIndexes() && (!IsReindexProcessing() || pg_class->rd_rel->relhasindex)) if (!IsIgnoringSystemIndexes() &&
(!IsReindexProcessing() || pg_class->rd_rel->relhasindex))
{ {
tuple = SearchSysCacheCopy(RELOID, tuple = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
...@@ -1248,11 +1265,21 @@ setRelhasindex(Oid relid, bool hasindex) ...@@ -1248,11 +1265,21 @@ setRelhasindex(Oid relid, bool hasindex)
} }
/* /*
* Update hasindex in pg_class. * Update fields in the pg_class tuple.
*/ */
if (pg_class_scan) if (pg_class_scan)
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE); LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_EXCLUSIVE);
((Form_pg_class) GETSTRUCT(tuple))->relhasindex = hasindex;
classtuple = (Form_pg_class) GETSTRUCT(tuple);
classtuple->relhasindex = hasindex;
if (isprimary)
classtuple->relhaspkey = true;
if (OidIsValid(reltoastidxid))
{
Assert(classtuple->relkind == RELKIND_TOASTVALUE);
classtuple->reltoastidxid = reltoastidxid;
}
if (pg_class_scan) if (pg_class_scan)
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK); LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
...@@ -1945,7 +1972,7 @@ activate_indexes_of_a_table(Oid relid, bool activate) ...@@ -1945,7 +1972,7 @@ activate_indexes_of_a_table(Oid relid, bool activate)
if (IndexesAreActive(relid, true)) if (IndexesAreActive(relid, true))
{ {
if (!activate) if (!activate)
setRelhasindex(relid, false); setRelhasindex(relid, false, false, InvalidOid);
else else
return false; return false;
} }
...@@ -2081,7 +2108,7 @@ reindex_relation(Oid relid, bool force) ...@@ -2081,7 +2108,7 @@ reindex_relation(Oid relid, bool force)
* For pg_class, relhasindex should be set to true here in * For pg_class, relhasindex should be set to true here in
* place. * place.
*/ */
setRelhasindex(relid, true); setRelhasindex(relid, true, false, InvalidOid);
CommandCounterIncrement(); CommandCounterIncrement();
/* /*
...@@ -2089,7 +2116,7 @@ reindex_relation(Oid relid, bool force) ...@@ -2089,7 +2116,7 @@ reindex_relation(Oid relid, bool force)
* keep consistency with WAL. * keep consistency with WAL.
*/ */
} }
setRelhasindex(relid, true); setRelhasindex(relid, true, false, InvalidOid);
} }
} }
SetReindexProcessing(old); SetReindexProcessing(old);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.80 2001/06/22 19:16:21 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.81 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
*/ */
char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] = char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] =
{AggregateNameTypeIndex}; {AggregateNameTypeIndex, AggregateOidIndex};
char *Name_pg_am_indices[Num_pg_am_indices] = char *Name_pg_am_indices[Num_pg_am_indices] =
{AmNameIndex, AmOidIndex}; {AmNameIndex, AmOidIndex};
char *Name_pg_amop_indices[Num_pg_amop_indices] = char *Name_pg_amop_indices[Num_pg_amop_indices] =
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.67 2001/07/12 20:35:54 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.68 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -160,7 +160,9 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp) ...@@ -160,7 +160,9 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp)
tupdesc = CreateTupleDescCopyConstr(OldHeapDesc); tupdesc = CreateTupleDescCopyConstr(OldHeapDesc);
OIDNewHeap = heap_create_with_catalog(NewName, tupdesc, OIDNewHeap = heap_create_with_catalog(NewName, tupdesc,
RELKIND_RELATION, istemp, OldHeap->rd_rel->relkind,
OldHeap->rd_rel->relhasoids,
istemp,
allowSystemTableMods); allowSystemTableMods);
/* /*
...@@ -227,7 +229,8 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName) ...@@ -227,7 +229,8 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName)
Old_pg_index_Form->indisprimary, Old_pg_index_Form->indisprimary,
allowSystemTableMods); allowSystemTableMods);
setRelhasindex(OIDNewHeap, true); setRelhasindex(OIDNewHeap, true,
Old_pg_index_Form->indisprimary, InvalidOid);
ReleaseSysCache(Old_pg_index_Tuple); ReleaseSysCache(Old_pg_index_Tuple);
ReleaseSysCache(Old_pg_index_relation_Tuple); ReleaseSysCache(Old_pg_index_relation_Tuple);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.139 2001/08/10 14:30:14 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.140 2001/08/10 18:57:34 tgl Exp $
* *
* NOTES * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
...@@ -102,7 +102,7 @@ PerformPortalFetch(char *name, ...@@ -102,7 +102,7 @@ PerformPortalFetch(char *name,
QueryDesc *queryDesc; QueryDesc *queryDesc;
EState *estate; EState *estate;
MemoryContext oldcontext; MemoryContext oldcontext;
bool faked_desc = false; bool temp_desc = false;
/* /*
* sanity checks * sanity checks
...@@ -130,24 +130,33 @@ PerformPortalFetch(char *name, ...@@ -130,24 +130,33 @@ PerformPortalFetch(char *name,
oldcontext = MemoryContextSwitchTo(PortalGetHeapMemory(portal)); oldcontext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
/* /*
* tell the destination to prepare to receive some tuples. * If the requested destination is not the same as the query's
* original destination, make a temporary QueryDesc with the proper
* destination. This supports MOVE, for example, which will pass in
* dest = None.
* *
* If we've been asked for a MOVE, make a temporary QueryDesc with the * EXCEPTION: if the query's original dest is RemoteInternal (ie, it's
* appropriate dummy destination. * a binary cursor) and the request is Remote, we do NOT override the
* original dest. This is necessary since a FETCH command will pass
* dest = Remote, not knowing whether the cursor is binary or not.
*/ */
queryDesc = PortalGetQueryDesc(portal); queryDesc = PortalGetQueryDesc(portal);
estate = PortalGetState(portal); estate = PortalGetState(portal);
if (dest != queryDesc->dest) /* MOVE */ if (dest != queryDesc->dest &&
!(queryDesc->dest == RemoteInternal && dest == Remote))
{ {
QueryDesc *qdesc = (QueryDesc *) palloc(sizeof(QueryDesc)); QueryDesc *qdesc = (QueryDesc *) palloc(sizeof(QueryDesc));
memcpy(qdesc, queryDesc, sizeof(QueryDesc)); memcpy(qdesc, queryDesc, sizeof(QueryDesc));
qdesc->dest = dest; qdesc->dest = dest;
queryDesc = qdesc; queryDesc = qdesc;
faked_desc = true; temp_desc = true;
} }
/*
* tell the destination to prepare to receive some tuples.
*/
BeginCommand(name, BeginCommand(name,
queryDesc->operation, queryDesc->operation,
PortalGetTupleDesc(portal), PortalGetTupleDesc(portal),
...@@ -156,7 +165,7 @@ PerformPortalFetch(char *name, ...@@ -156,7 +165,7 @@ PerformPortalFetch(char *name,
false, /* this is a portal fetch, not a "retrieve false, /* this is a portal fetch, not a "retrieve
* portal" */ * portal" */
tag, tag,
dest); queryDesc->dest);
/* /*
* Determine which direction to go in, and check to see if we're * Determine which direction to go in, and check to see if we're
...@@ -205,7 +214,7 @@ PerformPortalFetch(char *name, ...@@ -205,7 +214,7 @@ PerformPortalFetch(char *name,
/* /*
* Clean up and switch back to old context. * Clean up and switch back to old context.
*/ */
if (faked_desc) /* MOVE */ if (temp_desc)
pfree(queryDesc); pfree(queryDesc);
MemoryContextSwitchTo(oldcontext); MemoryContextSwitchTo(oldcontext);
...@@ -1004,8 +1013,7 @@ AlterTableDropColumn(const char *relationName, ...@@ -1004,8 +1013,7 @@ AlterTableDropColumn(const char *relationName,
#ifdef _DROP_COLUMN_HACK__ #ifdef _DROP_COLUMN_HACK__
Relation rel, Relation rel,
attrdesc; attrdesc;
Oid myrelid, Oid myrelid;
attoid;
HeapTuple reltup; HeapTuple reltup;
HeapTupleData classtuple; HeapTupleData classtuple;
Buffer buffer; Buffer buffer;
...@@ -1094,7 +1102,6 @@ AlterTableDropColumn(const char *relationName, ...@@ -1094,7 +1102,6 @@ AlterTableDropColumn(const char *relationName,
if (attnum <= 0) if (attnum <= 0)
elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped", elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped",
colName); colName);
attoid = tup->t_data->t_oid;
/* /*
* Check constraints/indices etc here * Check constraints/indices etc here
...@@ -1124,8 +1131,9 @@ AlterTableDropColumn(const char *relationName, ...@@ -1124,8 +1131,9 @@ AlterTableDropColumn(const char *relationName,
heap_close(attrdesc, NoLock); heap_close(attrdesc, NoLock);
heap_freetuple(tup); heap_freetuple(tup);
/* delete comments */ /* delete comment for this attribute only */
DeleteComments(attoid); CreateComments(RelationGetRelid(rel), RelOid_pg_class,
(int32) attnum, NULL);
/* delete attrdef */ /* delete attrdef */
drop_default(myrelid, attnum); drop_default(myrelid, attnum);
...@@ -1750,9 +1758,8 @@ AlterTableCreateToastTable(const char *relationName, bool silent) ...@@ -1750,9 +1758,8 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
Oid toast_idxid; Oid toast_idxid;
char toast_relname[NAMEDATALEN + 1]; char toast_relname[NAMEDATALEN + 1];
char toast_idxname[NAMEDATALEN + 1]; char toast_idxname[NAMEDATALEN + 1];
Relation toast_idxrel;
IndexInfo *indexInfo; IndexInfo *indexInfo;
Oid classObjectId[1]; Oid classObjectId[2];
/* /*
* permissions checking. XXX exactly what is appropriate here? * permissions checking. XXX exactly what is appropriate here?
...@@ -1870,50 +1877,49 @@ AlterTableCreateToastTable(const char *relationName, bool silent) ...@@ -1870,50 +1877,49 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
* so there's no need to handle the toast rel as temp. * so there's no need to handle the toast rel as temp.
*/ */
toast_relid = heap_create_with_catalog(toast_relname, tupdesc, toast_relid = heap_create_with_catalog(toast_relname, tupdesc,
RELKIND_TOASTVALUE, RELKIND_TOASTVALUE, false,
false, true); false, true);
/* make the toast relation visible, else index creation will fail */ /* make the toast relation visible, else index creation will fail */
CommandCounterIncrement(); CommandCounterIncrement();
/* create index on chunk_id */ /*
* Create unique index on chunk_id, chunk_seq.
*
* NOTE: the tuple toaster could actually function with a single-column
* index on chunk_id only. However, it couldn't be unique then. We
* want it to be unique as a check against the possibility of duplicate
* TOAST chunk OIDs. Too, the index might be a little more efficient this
* way, since btree isn't all that happy with large numbers of equal keys.
*/
indexInfo = makeNode(IndexInfo); indexInfo = makeNode(IndexInfo);
indexInfo->ii_NumIndexAttrs = 1; indexInfo->ii_NumIndexAttrs = 2;
indexInfo->ii_NumKeyAttrs = 1; indexInfo->ii_NumKeyAttrs = 2;
indexInfo->ii_KeyAttrNumbers[0] = 1; indexInfo->ii_KeyAttrNumbers[0] = 1;
indexInfo->ii_KeyAttrNumbers[1] = 2;
indexInfo->ii_Predicate = NIL; indexInfo->ii_Predicate = NIL;
indexInfo->ii_FuncOid = InvalidOid; indexInfo->ii_FuncOid = InvalidOid;
indexInfo->ii_Unique = false; indexInfo->ii_Unique = true;
classObjectId[0] = OID_OPS_OID; classObjectId[0] = OID_OPS_OID;
classObjectId[1] = INT4_OPS_OID;
index_create(toast_relname, toast_idxname, indexInfo, toast_idxid = index_create(toast_relname, toast_idxname, indexInfo,
BTREE_AM_OID, classObjectId, BTREE_AM_OID, classObjectId,
false, false, true); false, true, true);
/* /*
* Update toast rel's pg_class entry to show that it has an index. * Update toast rel's pg_class entry to show that it has an index.
* The index OID is stored into the reltoastidxid field for
* easy access by the tuple toaster.
*/ */
setRelhasindex(toast_relid, true); setRelhasindex(toast_relid, true, true, toast_idxid);
/*
* Make index visible
*/
CommandCounterIncrement();
/*
* Get the OID of the newly created index
*/
toast_idxrel = index_openr(toast_idxname);
toast_idxid = RelationGetRelid(toast_idxrel);
index_close(toast_idxrel);
/* /*
* Store the toast table- and index-Oid's in the relation tuple * Store the toast table's OID in the parent relation's tuple
*/ */
((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid = toast_relid; ((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid = toast_relid;
((Form_pg_class) GETSTRUCT(reltup))->reltoastidxid = toast_idxid;
simple_heap_update(class_rel, &reltup->t_self, reltup); simple_heap_update(class_rel, &reltup->t_self, reltup);
/* /*
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.140 2001/07/11 21:53:59 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.141 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -235,43 +235,45 @@ CopyDonePeek(FILE *fp, int c, int pickup) ...@@ -235,43 +235,45 @@ CopyDonePeek(FILE *fp, int c, int pickup)
/* /*
* DoCopy executes the SQL COPY statement. * DoCopy executes the SQL COPY statement.
*
* Either unload or reload contents of table <relname>, depending on <from>.
* (<from> = TRUE means we are inserting into the table.)
*
* If <pipe> is false, transfer is between the table and the file named
* <filename>. Otherwise, transfer is between the table and our regular
* input/output stream. The latter could be either stdin/stdout or a
* socket, depending on whether we're running under Postmaster control.
*
* Iff <binary>, unload or reload in the binary format, as opposed to the
* more wasteful but more robust and portable text format.
*
* Iff <oids>, unload or reload the format that includes OID information.
* On input, we accept OIDs whether or not the table has an OID column,
* but silently drop them if it does not. On output, we report an error
* if the user asks for OIDs in a table that has none (not providing an
* OID column might seem friendlier, but could seriously confuse programs).
*
* If in the text format, delimit columns with delimiter <delim> and print
* NULL values as <null_print>.
*
* When loading in the text format from an input stream (as opposed to
* a file), recognize a "." on a line by itself as EOF. Also recognize
* a stream EOF. When unloading in the text format to an output stream,
* write a "." on a line by itself at the end of the data.
*
* Do not allow a Postgres user without superuser privilege to read from
* or write to a file.
*
* Do not allow the copy if user doesn't have proper permission to access
* the table.
*/ */
void void
DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
char *filename, char *delim, char *null_print) char *filename, char *delim, char *null_print)
{ {
/*----------------------------------------------------------------------------
Either unload or reload contents of class <relname>, depending on <from>.
If <pipe> is false, transfer is between the class and the file named
<filename>. Otherwise, transfer is between the class and our regular
input/output stream. The latter could be either stdin/stdout or a
socket, depending on whether we're running under Postmaster control.
Iff <binary>, unload or reload in the binary format, as opposed to the
more wasteful but more robust and portable text format.
If in the text format, delimit columns with delimiter <delim> and print
NULL values as <null_print>.
When loading in the text format from an input stream (as opposed to
a file), recognize a "." on a line by itself as EOF. Also recognize
a stream EOF. When unloading in the text format to an output stream,
write a "." on a line by itself at the end of the data.
Iff <oids>, unload or reload the format that includes OID information.
Do not allow a Postgres user without superuser privilege to read from
or write to a file.
Do not allow the copy if user doesn't have proper permission to access
the class.
----------------------------------------------------------------------------*/
FILE *fp; FILE *fp;
Relation rel; Relation rel;
const AclMode required_access = from ? ACL_INSERT : ACL_SELECT; const AclMode required_access = (from ? ACL_INSERT : ACL_SELECT);
int result; int result;
/* /*
...@@ -305,10 +307,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, ...@@ -305,10 +307,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
if (from) if (from)
{ /* copy from file to database */ { /* copy from file to database */
if (rel->rd_rel->relkind == RELKIND_SEQUENCE) if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "You cannot change sequence relation %s", relname); {
if (rel->rd_rel->relkind == RELKIND_VIEW) if (rel->rd_rel->relkind == RELKIND_VIEW)
elog(ERROR, "You cannot copy view %s", relname); elog(ERROR, "You cannot copy view %s", relname);
else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
elog(ERROR, "You cannot change sequence relation %s", relname);
else
elog(ERROR, "You cannot copy object %s", relname);
}
if (pipe) if (pipe)
{ {
if (IsUnderPostmaster) if (IsUnderPostmaster)
...@@ -332,8 +339,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, ...@@ -332,8 +339,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
} }
else else
{ /* copy from database to file */ { /* copy from database to file */
if (rel->rd_rel->relkind != RELKIND_RELATION)
{
if (rel->rd_rel->relkind == RELKIND_VIEW) if (rel->rd_rel->relkind == RELKIND_VIEW)
elog(ERROR, "You cannot copy view %s", relname); elog(ERROR, "You cannot copy view %s", relname);
else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
elog(ERROR, "You cannot copy sequence %s", relname);
else
elog(ERROR, "You cannot copy object %s", relname);
}
if (pipe) if (pipe)
{ {
if (IsUnderPostmaster) if (IsUnderPostmaster)
...@@ -410,6 +424,10 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, ...@@ -410,6 +424,10 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp,
int16 fld_size; int16 fld_size;
char *string; char *string;
if (oids && !rel->rd_rel->relhasoids)
elog(ERROR, "COPY: table %s does not have OIDs",
RelationGetRelationName(rel));
tupDesc = rel->rd_att; tupDesc = rel->rd_att;
attr_count = rel->rd_att->natts; attr_count = rel->rd_att->natts;
attr = rel->rd_att->attrs; attr = rel->rd_att->attrs;
...@@ -706,6 +724,10 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, ...@@ -706,6 +724,10 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
elements = NULL; elements = NULL;
} }
/* Silently drop incoming OIDs if table does not have OIDs */
if (!rel->rd_rel->relhasoids)
oids = false;
values = (Datum *) palloc(attr_count * sizeof(Datum)); values = (Datum *) palloc(attr_count * sizeof(Datum));
nulls = (char *) palloc(attr_count * sizeof(char)); nulls = (char *) palloc(attr_count * sizeof(char));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.78 2001/06/22 21:37:14 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.79 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
*/ */
static List *MergeAttributes(List *schema, List *supers, bool istemp, static List *MergeAttributes(List *schema, List *supers, bool istemp,
List **supOids, List **supconstr); List **supOids, List **supconstr, bool *supHasOids);
static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno); static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno);
static void StoreCatalogInheritance(Oid relationId, List *supers); static void StoreCatalogInheritance(Oid relationId, List *supers);
static int findAttrByName(const char *attributeName, List *schema); static int findAttrByName(const char *attributeName, List *schema);
...@@ -57,6 +57,7 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -57,6 +57,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
TupleDesc descriptor; TupleDesc descriptor;
List *inheritOids; List *inheritOids;
List *old_constraints; List *old_constraints;
bool parentHasOids;
List *rawDefaults; List *rawDefaults;
List *listptr; List *listptr;
int i; int i;
...@@ -73,7 +74,7 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -73,7 +74,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
* including inherited attributes. * including inherited attributes.
*/ */
schema = MergeAttributes(schema, stmt->inhRelnames, stmt->istemp, schema = MergeAttributes(schema, stmt->inhRelnames, stmt->istemp,
&inheritOids, &old_constraints); &inheritOids, &old_constraints, &parentHasOids);
numberOfAttributes = length(schema); numberOfAttributes = length(schema);
if (numberOfAttributes <= 0) if (numberOfAttributes <= 0)
...@@ -135,7 +136,9 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -135,7 +136,9 @@ DefineRelation(CreateStmt *stmt, char relkind)
} }
relationId = heap_create_with_catalog(relname, descriptor, relationId = heap_create_with_catalog(relname, descriptor,
relkind, stmt->istemp, relkind,
stmt->hasoids || parentHasOids,
stmt->istemp,
allowSystemTableMods); allowSystemTableMods);
StoreCatalogInheritance(relationId, inheritOids); StoreCatalogInheritance(relationId, inheritOids);
...@@ -248,6 +251,7 @@ TruncateRelation(char *name) ...@@ -248,6 +251,7 @@ TruncateRelation(char *name)
* 'supOids' receives an integer list of the OIDs of the parent relations. * 'supOids' receives an integer list of the OIDs of the parent relations.
* 'supconstr' receives a list of constraints belonging to the parents, * 'supconstr' receives a list of constraints belonging to the parents,
* updated as necessary to be valid for the child. * updated as necessary to be valid for the child.
* 'supHasOids' is set TRUE if any parent has OIDs, else it is set FALSE.
* *
* Return value: * Return value:
* Completed schema list. * Completed schema list.
...@@ -293,12 +297,13 @@ TruncateRelation(char *name) ...@@ -293,12 +297,13 @@ TruncateRelation(char *name)
*/ */
static List * static List *
MergeAttributes(List *schema, List *supers, bool istemp, MergeAttributes(List *schema, List *supers, bool istemp,
List **supOids, List **supconstr) List **supOids, List **supconstr, bool *supHasOids)
{ {
List *entry; List *entry;
List *inhSchema = NIL; List *inhSchema = NIL;
List *parentOids = NIL; List *parentOids = NIL;
List *constraints = NIL; List *constraints = NIL;
bool parentHasOids = false;
bool have_bogus_defaults = false; bool have_bogus_defaults = false;
char *bogus_marker = "Bogus!"; /* marks conflicting defaults */ char *bogus_marker = "Bogus!"; /* marks conflicting defaults */
int child_attno; int child_attno;
...@@ -341,7 +346,8 @@ MergeAttributes(List *schema, List *supers, bool istemp, ...@@ -341,7 +346,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
/* /*
* Scan the parents left-to-right, and merge their attributes to form * Scan the parents left-to-right, and merge their attributes to form
* a list of inherited attributes (inhSchema). * a list of inherited attributes (inhSchema). Also check to see if
* we need to inherit an OID column.
*/ */
child_attno = 0; child_attno = 0;
foreach(entry, supers) foreach(entry, supers)
...@@ -371,6 +377,8 @@ MergeAttributes(List *schema, List *supers, bool istemp, ...@@ -371,6 +377,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
parentOids = lappendi(parentOids, relation->rd_id); parentOids = lappendi(parentOids, relation->rd_id);
setRelhassubclassInRelation(relation->rd_id, true); setRelhassubclassInRelation(relation->rd_id, true);
parentHasOids |= relation->rd_rel->relhasoids;
tupleDesc = RelationGetDescr(relation); tupleDesc = RelationGetDescr(relation);
constr = tupleDesc->constr; constr = tupleDesc->constr;
...@@ -598,6 +606,7 @@ MergeAttributes(List *schema, List *supers, bool istemp, ...@@ -598,6 +606,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
*supOids = parentOids; *supOids = parentOids;
*supconstr = constraints; *supconstr = constraints;
*supHasOids = parentHasOids;
return schema; return schema;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.77 2001/08/04 00:14:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.78 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -354,15 +354,15 @@ dropdb(const char *dbname) ...@@ -354,15 +354,15 @@ dropdb(const char *dbname)
heap_endscan(pgdbscan); heap_endscan(pgdbscan);
/* Delete any comments associated with the database */
DeleteComments(db_id, RelationGetRelid(pgdbrel));
/* /*
* Close pg_database, but keep exclusive lock till commit to ensure * Close pg_database, but keep exclusive lock till commit to ensure
* that any new backend scanning pg_database will see the tuple dead. * that any new backend scanning pg_database will see the tuple dead.
*/ */
heap_close(pgdbrel, NoLock); heap_close(pgdbrel, NoLock);
/* Delete any comments associated with the database */
DeleteComments(db_id);
/* /*
* Drop pages for this database that are in the shared buffer cache. * Drop pages for this database that are in the shared buffer cache.
* This is important to ensure that no remaining backend tries to * This is important to ensure that no remaining backend tries to
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.55 2001/08/09 18:28:17 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.56 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -212,7 +212,7 @@ DefineIndex(char *heapRelationName, ...@@ -212,7 +212,7 @@ DefineIndex(char *heapRelationName,
* backends to flush their relcache entries and in particular their * backends to flush their relcache entries and in particular their
* cached lists of the indexes for this relation. * cached lists of the indexes for this relation.
*/ */
setRelhasindex(relationId, true); setRelhasindex(relationId, true, primary, InvalidOid);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.61 2001/06/05 19:34:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.62 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -85,9 +85,8 @@ RemoveOperator(char *operatorName, /* operator name */ ...@@ -85,9 +85,8 @@ RemoveOperator(char *operatorName, /* operator name */
elog(ERROR, "RemoveOperator: operator '%s': permission denied", elog(ERROR, "RemoveOperator: operator '%s': permission denied",
operatorName); operatorName);
/*** Delete any comments associated with this operator ***/ /* Delete any comments associated with this operator */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
DeleteComments(tup->t_data->t_oid);
simple_heap_delete(relation, &tup->t_self); simple_heap_delete(relation, &tup->t_self);
...@@ -146,11 +145,8 @@ SingleOpOperatorRemove(Oid typeOid) ...@@ -146,11 +145,8 @@ SingleOpOperatorRemove(Oid typeOid)
scan = heap_beginscan(rel, 0, SnapshotNow, 1, key); scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
while (HeapTupleIsValid(tup = heap_getnext(scan, 0))) while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
{ {
/* Delete any comments associated with this operator */
/*** This is apparently a routine not in use, but remove ***/ DeleteComments(tup->t_data->t_oid, RelationGetRelid(rel));
/*** any comments anyways ***/
DeleteComments(tup->t_data->t_oid);
simple_heap_delete(rel, &tup->t_self); simple_heap_delete(rel, &tup->t_self);
} }
...@@ -242,7 +238,6 @@ RemoveType(char *typeName) /* type name to be removed */ ...@@ -242,7 +238,6 @@ RemoveType(char *typeName) /* type name to be removed */
{ {
Relation relation; Relation relation;
HeapTuple tup; HeapTuple tup;
Oid typeOid;
char *shadow_type; char *shadow_type;
if (!pg_ownercheck(GetUserId(), typeName, TYPENAME)) if (!pg_ownercheck(GetUserId(), typeName, TYPENAME))
...@@ -257,11 +252,8 @@ RemoveType(char *typeName) /* type name to be removed */ ...@@ -257,11 +252,8 @@ RemoveType(char *typeName) /* type name to be removed */
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
elog(ERROR, "RemoveType: type '%s' does not exist", typeName); elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
typeOid = tup->t_data->t_oid; /* Delete any comments associated with this type */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
/*** Delete any comments associated with this type ***/
DeleteComments(typeOid);
simple_heap_delete(relation, &tup->t_self); simple_heap_delete(relation, &tup->t_self);
...@@ -347,9 +339,8 @@ RemoveFunction(char *functionName, /* function name to be removed */ ...@@ -347,9 +339,8 @@ RemoveFunction(char *functionName, /* function name to be removed */
elog(NOTICE, "Removing built-in function \"%s\"", functionName); elog(NOTICE, "Removing built-in function \"%s\"", functionName);
} }
/*** Delete any comments associated with this function ***/ /* Delete any comments associated with this function */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
DeleteComments(tup->t_data->t_oid);
simple_heap_delete(relation, &tup->t_self); simple_heap_delete(relation, &tup->t_self);
...@@ -421,9 +412,8 @@ RemoveAggregate(char *aggName, char *aggType) ...@@ -421,9 +412,8 @@ RemoveAggregate(char *aggName, char *aggType)
} }
} }
/*** Remove any comments related to this aggregate ***/ /* Remove any comments related to this aggregate */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
DeleteComments(tup->t_data->t_oid);
simple_heap_delete(relation, &tup->t_self); simple_heap_delete(relation, &tup->t_self);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.61 2001/06/29 21:08:24 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.62 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -161,9 +161,10 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -161,9 +161,10 @@ DefineSequence(CreateSeqStmt *seq)
} }
stmt->relname = seq->seqname; stmt->relname = seq->seqname;
stmt->istemp = seq->istemp;
stmt->inhRelnames = NIL; stmt->inhRelnames = NIL;
stmt->constraints = NIL; stmt->constraints = NIL;
stmt->istemp = seq->istemp;
stmt->hasoids = false;
DefineRelation(stmt, RELKIND_SEQUENCE); DefineRelation(stmt, RELKIND_SEQUENCE);
......
...@@ -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
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.94 2001/08/02 15:59:28 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.95 2001/08/10 18:57:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -336,10 +336,8 @@ DropTrigger(DropTrigStmt *stmt) ...@@ -336,10 +336,8 @@ DropTrigger(DropTrigStmt *stmt)
if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0) if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
{ {
/* Delete any comments associated with this trigger */
/*** Delete any comments associated with this trigger ***/ DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel));
DeleteComments(tuple->t_data->t_oid);
simple_heap_delete(tgrel, &tuple->t_self); simple_heap_delete(tgrel, &tuple->t_self);
tgfound++; tgfound++;
...@@ -407,10 +405,8 @@ RelationRemoveTriggers(Relation rel) ...@@ -407,10 +405,8 @@ RelationRemoveTriggers(Relation rel)
while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0))) while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0)))
{ {
/* Delete any comments associated with this trigger */
/*** Delete any comments associated with this trigger ***/ DeleteComments(tup->t_data->t_oid, RelationGetRelid(tgrel));
DeleteComments(tup->t_data->t_oid);
simple_heap_delete(tgrel, &tup->t_self); simple_heap_delete(tgrel, &tup->t_self);
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.206 2001/07/18 00:46:24 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.207 2001/08/10 18:57:35 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -434,6 +434,12 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples, ...@@ -434,6 +434,12 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
pgcform->relpages = (int32) num_pages; pgcform->relpages = (int32) num_pages;
pgcform->reltuples = num_tuples; pgcform->reltuples = num_tuples;
pgcform->relhasindex = hasindex; pgcform->relhasindex = hasindex;
/*
* If we have discovered that there are no indexes, then there's
* no primary key either. This could be done more thoroughly...
*/
if (!hasindex)
pgcform->relhaspkey = false;
/* invalidate the tuple in the cache and write the buffer */ /* invalidate the tuple in the cache and write the buffer */
RelationInvalidateHeapTuple(rd, &rtup); RelationInvalidateHeapTuple(rd, &rtup);
...@@ -904,7 +910,8 @@ scan_heap(VRelStats *vacrelstats, Relation onerel, ...@@ -904,7 +910,8 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
/* /*
* Other checks... * Other checks...
*/ */
if (!OidIsValid(tuple.t_data->t_oid)) if (!OidIsValid(tuple.t_data->t_oid) &&
onerel->rd_rel->relhasoids)
elog(NOTICE, "Rel %s: TID %u/%u: OID IS INVALID. TUPGONE %d.", elog(NOTICE, "Rel %s: TID %u/%u: OID IS INVALID. TUPGONE %d.",
relname, blkno, offnum, (int) tupgone); relname, blkno, offnum, (int) tupgone);
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.3 2001/07/18 00:46:25 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.4 2001/08/10 18:57:35 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -339,7 +339,8 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, ...@@ -339,7 +339,8 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
/* /*
* Other checks... * Other checks...
*/ */
if (!OidIsValid(tuple.t_data->t_oid)) if (!OidIsValid(tuple.t_data->t_oid) &&
onerel->rd_rel->relhasoids)
elog(NOTICE, "Rel %s: TID %u/%u: OID IS INVALID. TUPGONE %d.", elog(NOTICE, "Rel %s: TID %u/%u: OID IS INVALID. TUPGONE %d.",
relname, blkno, offnum, (int) tupgone); relname, blkno, offnum, (int) tupgone);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: view.c,v 1.54 2001/03/22 03:59:25 momjian Exp $ * $Id: view.c,v 1.55 2001/08/10 18:57:35 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -88,10 +88,11 @@ DefineVirtualRelation(char *relname, List *tlist) ...@@ -88,10 +88,11 @@ DefineVirtualRelation(char *relname, List *tlist)
* nil... * nil...
*/ */
createStmt->relname = relname; createStmt->relname = relname;
createStmt->istemp = false;
createStmt->tableElts = attrList; createStmt->tableElts = attrList;
createStmt->inhRelnames = NIL; createStmt->inhRelnames = NIL;
createStmt->constraints = NIL; createStmt->constraints = NIL;
createStmt->istemp = false;
createStmt->hasoids = false;
/* /*
* finally create the relation... * finally create the relation...
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.144 2001/06/22 19:16:22 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.145 2001/08/10 18:57:35 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -761,7 +761,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) ...@@ -761,7 +761,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
intoRelationId = intoRelationId =
heap_create_with_catalog(intoName, heap_create_with_catalog(intoName,
tupdesc, tupdesc,
RELKIND_RELATION, RELKIND_RELATION, true,
parseTree->isTemp, parseTree->isTemp,
allowSystemTableMods); allowSystemTableMods);
......
...@@ -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
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.151 2001/08/10 14:30:14 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.152 2001/08/10 18:57:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1967,11 +1967,12 @@ _copyCreateStmt(CreateStmt *from) ...@@ -1967,11 +1967,12 @@ _copyCreateStmt(CreateStmt *from)
{ {
CreateStmt *newnode = makeNode(CreateStmt); CreateStmt *newnode = makeNode(CreateStmt);
newnode->istemp = from->istemp;
newnode->relname = pstrdup(from->relname); newnode->relname = pstrdup(from->relname);
Node_Copy(from, newnode, tableElts); Node_Copy(from, newnode, tableElts);
Node_Copy(from, newnode, inhRelnames); Node_Copy(from, newnode, inhRelnames);
Node_Copy(from, newnode, constraints); Node_Copy(from, newnode, constraints);
newnode->istemp = from->istemp;
newnode->hasoids = from->hasoids;
return newnode; return newnode;
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.99 2001/08/10 14:30:14 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.100 2001/08/10 18:57:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -819,8 +819,6 @@ _equalCopyStmt(CopyStmt *a, CopyStmt *b) ...@@ -819,8 +819,6 @@ _equalCopyStmt(CopyStmt *a, CopyStmt *b)
static bool static bool
_equalCreateStmt(CreateStmt *a, CreateStmt *b) _equalCreateStmt(CreateStmt *a, CreateStmt *b)
{ {
if (a->istemp != b->istemp)
return false;
if (!equalstr(a->relname, b->relname)) if (!equalstr(a->relname, b->relname))
return false; return false;
if (!equal(a->tableElts, b->tableElts)) if (!equal(a->tableElts, b->tableElts))
...@@ -829,6 +827,10 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b) ...@@ -829,6 +827,10 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
return false; return false;
if (!equal(a->constraints, b->constraints)) if (!equal(a->constraints, b->constraints))
return false; return false;
if (a->istemp != b->istemp)
return false;
if (a->hasoids != b->hasoids)
return false;
return true; return true;
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.142 2001/06/19 22:39:11 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.143 2001/08/10 18:57:36 tgl Exp $
* *
* NOTES * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
...@@ -108,9 +108,6 @@ _outCreateStmt(StringInfo str, CreateStmt *node) ...@@ -108,9 +108,6 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
appendStringInfo(str, " CREATE :relname "); appendStringInfo(str, " CREATE :relname ");
_outToken(str, node->relname); _outToken(str, node->relname);
appendStringInfo(str, " :istemp %s ",
booltostr(node->istemp));
appendStringInfo(str, " :columns "); appendStringInfo(str, " :columns ");
_outNode(str, node->tableElts); _outNode(str, node->tableElts);
...@@ -119,6 +116,10 @@ _outCreateStmt(StringInfo str, CreateStmt *node) ...@@ -119,6 +116,10 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
appendStringInfo(str, " :constraints "); appendStringInfo(str, " :constraints ");
_outNode(str, node->constraints); _outNode(str, node->constraints);
appendStringInfo(str, " :istemp %s :hasoids %s ",
booltostr(node->istemp),
booltostr(node->hasoids));
} }
static void static void
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.242 2001/08/10 14:30:14 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.243 2001/08/10 18:57:36 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -198,7 +198,7 @@ static void doNegateFloat(Value *v); ...@@ -198,7 +198,7 @@ static void doNegateFloat(Value *v);
%type <typnam> func_arg, func_return, func_type, aggr_argtype %type <typnam> func_arg, func_return, func_type, aggr_argtype
%type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp %type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp, OptWithOids
%type <list> for_update_clause, opt_for_update_clause, update_list %type <list> for_update_clause, opt_for_update_clause, update_list
%type <boolean> opt_all %type <boolean> opt_all
...@@ -1174,14 +1174,15 @@ copy_null: WITH NULL_P AS Sconst { $$ = $4; } ...@@ -1174,14 +1174,15 @@ copy_null: WITH NULL_P AS Sconst { $$ = $4; }
* *
*****************************************************************************/ *****************************************************************************/
CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')' OptInherit CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')' OptInherit OptWithOids
{ {
CreateStmt *n = makeNode(CreateStmt); CreateStmt *n = makeNode(CreateStmt);
n->istemp = $2;
n->relname = $4; n->relname = $4;
n->tableElts = $6; n->tableElts = $6;
n->inhRelnames = $8; n->inhRelnames = $8;
n->constraints = NIL; n->constraints = NIL;
n->istemp = $2;
n->hasoids = $9;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -1541,6 +1542,12 @@ OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; } ...@@ -1541,6 +1542,12 @@ OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
| /*EMPTY*/ { $$ = NIL; } | /*EMPTY*/ { $$ = NIL; }
; ;
OptWithOids: WITH OIDS { $$ = TRUE; }
| WITHOUT OIDS { $$ = FALSE; }
| /*EMPTY*/ { $$ = TRUE; }
;
/* /*
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
* SELECT ... INTO. * SELECT ... INTO.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.55 2001/05/07 00:43:23 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.56 2001/08/10 18:57:37 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "rewrite/rewriteManip.h" #include "rewrite/rewriteManip.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/syscache.h"
static Node *scanNameSpaceForRefname(ParseState *pstate, Node *nsnode, static Node *scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
...@@ -38,6 +39,7 @@ static Node *scanJoinForColumn(JoinExpr *join, char *colname, ...@@ -38,6 +39,7 @@ static Node *scanJoinForColumn(JoinExpr *join, char *colname,
int sublevels_up); int sublevels_up);
static bool isForUpdate(ParseState *pstate, char *relname); static bool isForUpdate(ParseState *pstate, char *relname);
static List *expandNamesVars(ParseState *pstate, List *names, List *vars); static List *expandNamesVars(ParseState *pstate, List *names, List *vars);
static int specialAttNum(char *a);
static void warnAutoRange(ParseState *pstate, char *refname); static void warnAutoRange(ParseState *pstate, char *refname);
...@@ -318,13 +320,21 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname) ...@@ -318,13 +320,21 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
*/ */
if (rte->relid != InvalidOid) if (rte->relid != InvalidOid)
{ {
/* quick check to see if name could be a system column */
attnum = specialAttNum(colname); attnum = specialAttNum(colname);
if (attnum != InvalidAttrNumber) if (attnum != InvalidAttrNumber)
{
/* now check to see if column actually is defined */
if (SearchSysCacheExists(ATTNUM,
ObjectIdGetDatum(rte->relid),
Int16GetDatum(attnum),
0, 0))
{ {
result = (Node *) make_var(pstate, rte, attnum); result = (Node *) make_var(pstate, rte, attnum);
rte->checkForRead = true; rte->checkForRead = true;
} }
} }
}
return result; return result;
} }
...@@ -968,7 +978,10 @@ attnameAttNum(Relation rd, char *a) ...@@ -968,7 +978,10 @@ attnameAttNum(Relation rd, char *a)
return i + 1; return i + 1;
if ((i = specialAttNum(a)) != InvalidAttrNumber) if ((i = specialAttNum(a)) != InvalidAttrNumber)
{
if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
return i; return i;
}
/* on failure */ /* on failure */
elog(ERROR, "Relation '%s' does not have attribute '%s'", elog(ERROR, "Relation '%s' does not have attribute '%s'",
...@@ -977,10 +990,15 @@ attnameAttNum(Relation rd, char *a) ...@@ -977,10 +990,15 @@ attnameAttNum(Relation rd, char *a)
} }
/* specialAttNum() /* specialAttNum()
*
* Check attribute name to see if it is "special", e.g. "oid". * Check attribute name to see if it is "special", e.g. "oid".
* - thomas 2000-02-07 * - thomas 2000-02-07
*
* Note: this only discovers whether the name could be a system attribute.
* Caller needs to verify that it really is an attribute of the rel,
* at least in the case of "oid", which is now optional.
*/ */
int static int
specialAttNum(char *a) specialAttNum(char *a)
{ {
int i; int i;
...@@ -993,38 +1011,14 @@ specialAttNum(char *a) ...@@ -993,38 +1011,14 @@ specialAttNum(char *a)
} }
#ifdef NOT_USED
/*
* Given range variable, return whether attribute of this name
* is a set.
* NOTE the ASSUMPTION here that no system attributes are, or ever
* will be, sets.
*
* This should only be used if the relation is already
* heap_open()'ed. Use the cache version get_attisset()
* for access to non-opened relations.
*/
bool
attnameIsSet(Relation rd, char *name)
{
int i;
/* First check if this is a system attribute */
for (i = 0; i < SPECIALS; i++)
{
if (strcmp(special_attr[i].attrname, name) == 0)
return false; /* no sys attr is a set */
}
return get_attisset(RelationGetRelid(rd), name);
}
#endif
/* given attribute id, return type of that attribute */ /* given attribute id, return type of that attribute */
/* /*
* This should only be used if the relation is already * This should only be used if the relation is already
* heap_open()'ed. Use the cache version get_atttype() * heap_open()'ed. Use the cache version get_atttype()
* for access to non-opened relations. * for access to non-opened relations.
*
* Note: we don't bother to check rd->rd_rel->relhasoids; we assume that
* the caller will only ask about OID if that column has been found valid.
*/ */
Oid Oid
attnumTypeId(Relation rd, int attid) attnumTypeId(Relation rd, int attid)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.44 2001/03/22 03:59:44 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.45 2001/08/10 18:57:37 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -119,7 +119,7 @@ RemoveRewriteRule(char *ruleName) ...@@ -119,7 +119,7 @@ RemoveRewriteRule(char *ruleName)
/* /*
* Delete any comments associated with this rule * Delete any comments associated with this rule
*/ */
DeleteComments(ruleId); DeleteComments(ruleId, RelationGetRelid(RewriteRelation));
/* /*
* Now delete the pg_rewrite tuple for the rule * Now delete the pg_rewrite tuple for the rule
...@@ -175,10 +175,8 @@ RelationRemoveRules(Oid relid) ...@@ -175,10 +175,8 @@ RelationRemoveRules(Oid relid)
while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0))) while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
{ {
/* Delete any comments associated with this rule */
/*** Delete any comments associated with this relation ***/ DeleteComments(tuple->t_data->t_oid, RelationGetRelid(RewriteRelation));
DeleteComments(tuple->t_data->t_oid);
simple_heap_delete(RewriteRelation, &tuple->t_self); simple_heap_delete(RewriteRelation, &tuple->t_self);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.141 2001/06/29 21:08:25 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.142 2001/08/10 18:57:37 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1211,6 +1211,7 @@ formrdesc(char *relationName, ...@@ -1211,6 +1211,7 @@ formrdesc(char *relationName,
relation->rd_rel->relpages = 1; relation->rd_rel->relpages = 1;
relation->rd_rel->reltuples = 1; relation->rd_rel->reltuples = 1;
relation->rd_rel->relkind = RELKIND_RELATION; relation->rd_rel->relkind = RELKIND_RELATION;
relation->rd_rel->relhasoids = true;
relation->rd_rel->relnatts = (int16) natts; relation->rd_rel->relnatts = (int16) natts;
/* /*
...@@ -1988,6 +1989,7 @@ RelationBuildLocalRelation(const char *relname, ...@@ -1988,6 +1989,7 @@ RelationBuildLocalRelation(const char *relname,
strcpy(RelationGetPhysicalRelationName(rel), relname); strcpy(RelationGetPhysicalRelationName(rel), relname);
rel->rd_rel->relkind = RELKIND_UNCATALOGED; rel->rd_rel->relkind = RELKIND_UNCATALOGED;
rel->rd_rel->relhasoids = true;
rel->rd_rel->relnatts = natts; rel->rd_rel->relnatts = natts;
rel->rd_rel->reltype = InvalidOid; rel->rd_rel->reltype = InvalidOid;
if (tupDesc->constr) if (tupDesc->constr)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.63 2001/06/18 03:35:07 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.64 2001/08/10 18:57:37 tgl Exp $
* *
* NOTES * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
...@@ -485,6 +485,28 @@ SearchSysCacheCopy(int cacheId, ...@@ -485,6 +485,28 @@ SearchSysCacheCopy(int cacheId,
return newtuple; return newtuple;
} }
/*
* SearchSysCacheExists
*
* A convenience routine that just probes to see if a tuple can be found.
* No lock is retained on the syscache entry.
*/
bool
SearchSysCacheExists(int cacheId,
Datum key1,
Datum key2,
Datum key3,
Datum key4)
{
HeapTuple tuple;
tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
if (!HeapTupleIsValid(tuple))
return false;
ReleaseSysCache(tuple);
return true;
}
/* /*
* GetSysCacheOid * GetSysCacheOid
* *
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # Portions Copyright (c) 1994, Regents of the University of California
# #
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.131 2001/07/31 01:16:09 tgl Exp $ # $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.132 2001/08/10 18:57:38 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -484,9 +484,14 @@ chmod 0600 "$PGDATA"/pg_hba.conf "$PGDATA"/pg_ident.conf \ ...@@ -484,9 +484,14 @@ chmod 0600 "$PGDATA"/pg_hba.conf "$PGDATA"/pg_ident.conf \
# To break an SQL command across lines in this script, backslash-escape all # To break an SQL command across lines in this script, backslash-escape all
# internal newlines in the command. # internal newlines in the command.
echo "Initializing pg_shadow." if [ "$debug" = yes ]
then
PGSQL_OPT="-O -F -D$PGDATA"
else
PGSQL_OPT="-o /dev/null -O -F -D$PGDATA"
fi
PGSQL_OPT="-o /dev/null -O -F -D$PGDATA" echo "Initializing pg_shadow."
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
-- Create a trigger so that direct updates to pg_shadow will be written -- Create a trigger so that direct updates to pg_shadow will be written
...@@ -682,7 +687,7 @@ CREATE VIEW pg_statio_all_tables AS \ ...@@ -682,7 +687,7 @@ CREATE VIEW pg_statio_all_tables AS \
FROM pg_class C FULL OUTER JOIN \ FROM pg_class C FULL OUTER JOIN \
pg_index I ON C.oid = I.indrelid FULL OUTER JOIN \ pg_index I ON C.oid = I.indrelid FULL OUTER JOIN \
pg_class T ON C.reltoastrelid = T.oid FULL OUTER JOIN \ pg_class T ON C.reltoastrelid = T.oid FULL OUTER JOIN \
pg_class X ON C.reltoastidxid = X.oid \ pg_class X ON T.reltoastidxid = X.oid \
WHERE C.relkind = 'r' \ WHERE C.relkind = 'r' \
GROUP BY C.oid, C.relname, T.oid, X.oid; GROUP BY C.oid, C.relname, T.oid, X.oid;
...@@ -793,23 +798,24 @@ fi ...@@ -793,23 +798,24 @@ fi
echo "Loading pg_description." echo "Loading pg_description."
( (
echo "COPY pg_description FROM STDIN;"; cat <<EOF
CREATE TEMP TABLE tmp_pg_description ( \
objoid oid, \
classname name, \
objsubid int4, \
description text) WITHOUT OIDS;
COPY tmp_pg_description FROM STDIN;
EOF
cat "$POSTGRES_DESCR" cat "$POSTGRES_DESCR"
cat <<EOF
\.
INSERT INTO pg_description SELECT \
t.objoid, c.oid, t.objsubid, t.description \
FROM tmp_pg_description t, pg_class c WHERE c.relname = t.classname;
EOF
) \ ) \
| "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely | "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely
echo "Setting lastsysoid."
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
UPDATE pg_database SET \
datistemplate = 't', \
datlastsysoid = (SELECT max(oid) FROM pg_description) \
WHERE datname = 'template1';
EOF
if [ "$?" -ne 0 ]; then
exit_nicely
fi
echo "Vacuuming database." echo "Vacuuming database."
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
...@@ -823,10 +829,17 @@ echo "Copying template1 to template0." ...@@ -823,10 +829,17 @@ echo "Copying template1 to template0."
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
CREATE DATABASE template0; CREATE DATABASE template0;
UPDATE pg_database SET \ UPDATE pg_database SET \
datistemplate = 't', \ datistemplate = 't', \
datallowconn = 'f' \ datallowconn = 'f' \
WHERE datname = 'template0'; WHERE datname = 'template0';
-- We use the OID of template0 to determine lastsysoid
UPDATE pg_database SET datlastsysoid = \
(SELECT oid - 1 FROM pg_database WHERE datname = 'template0');
VACUUM FULL pg_database; VACUUM FULL pg_database;
EOF EOF
if [ "$?" -ne 0 ]; then if [ "$?" -ne 0 ]; then
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_dump.h,v 1.68 2001/08/03 19:43:05 tgl Exp $ * $Id: pg_dump.h,v 1.69 2001/08/10 18:57:38 tgl Exp $
* *
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
* *
...@@ -63,7 +63,7 @@ typedef struct _funcInfo ...@@ -63,7 +63,7 @@ typedef struct _funcInfo
char *oid; char *oid;
char *proname; char *proname;
char *proowner; char *proowner;
int lang; Oid lang;
int nargs; int nargs;
char *argtypes[FUNC_MAX_ARGS]; char *argtypes[FUNC_MAX_ARGS];
char *prorettype; char *prorettype;
...@@ -97,6 +97,7 @@ typedef struct _tableInfo ...@@ -97,6 +97,7 @@ typedef struct _tableInfo
* created after the base table was created. * created after the base table was created.
*/ */
bool sequence; bool sequence;
bool hasoids; /* does it have OIDs? */
int numatts; /* number of attributes */ int numatts; /* number of attributes */
int *inhAttrs; /* an array of flags, one for each int *inhAttrs; /* an array of flags, one for each
* attribute if the value is 1, then this * attribute if the value is 1, then this
...@@ -104,7 +105,6 @@ typedef struct _tableInfo ...@@ -104,7 +105,6 @@ typedef struct _tableInfo
int *inhAttrDef; /* Flags indicating if attrdef is inherited */ int *inhAttrDef; /* Flags indicating if attrdef is inherited */
int *inhNotNull; /* Flags indicating if NOT NULL in inherited */ int *inhNotNull; /* Flags indicating if NOT NULL in inherited */
char **attnames; /* the attribute names */ char **attnames; /* the attribute names */
char **attoids; /* oids of the various attributes */
char **atttypedefns; /* formatted column type definitions */ char **atttypedefns; /* formatted column type definitions */
char **typnames; /* fill out attributes */ char **typnames; /* fill out attributes */
bool *notnull; /* Not null constraints of an attribute */ bool *notnull; /* Not null constraints of an attribute */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* *
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.37 2001/08/09 03:32:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.38 2001/08/10 18:57:39 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "describe.h" #include "describe.h"
...@@ -51,7 +51,7 @@ describeAggregates(const char *name) ...@@ -51,7 +51,7 @@ describeAggregates(const char *name)
" WHEN 0 THEN CAST('%s' AS text)\n" " WHEN 0 THEN CAST('%s' AS text)\n"
" ELSE format_type(a.aggbasetype, NULL)\n" " ELSE format_type(a.aggbasetype, NULL)\n"
" END AS \"%s\",\n" " END AS \"%s\",\n"
" obj_description(a.oid) as \"%s\"\n" " obj_description(a.oid, 'pg_aggregate') as \"%s\"\n"
"FROM pg_aggregate a\n", "FROM pg_aggregate a\n",
_("Name"), _("(all types)"), _("Name"), _("(all types)"),
_("Data type"), _("Description") ); _("Data type"), _("Description") );
...@@ -105,7 +105,7 @@ describeFunctions(const char *name, bool verbose) ...@@ -105,7 +105,7 @@ describeFunctions(const char *name, bool verbose)
",\n u.usename as \"%s\",\n" ",\n u.usename as \"%s\",\n"
" l.lanname as \"%s\",\n" " l.lanname as \"%s\",\n"
" p.prosrc as \"%s\",\n" " p.prosrc as \"%s\",\n"
" obj_description(p.oid) as \"%s\"", " obj_description(p.oid, 'pg_proc') as \"%s\"",
_("Owner"), _("Language"), _("Owner"), _("Language"),
_("Source code"), _("Description") ); _("Source code"), _("Description") );
...@@ -165,7 +165,7 @@ describeTypes(const char *name, bool verbose) ...@@ -165,7 +165,7 @@ describeTypes(const char *name, bool verbose)
" END AS \"%s\",\n", " END AS \"%s\",\n",
_("Internal name"), _("Size") ); _("Internal name"), _("Size") );
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
" obj_description(t.oid) as \"%s\"\n", " obj_description(t.oid, 'pg_type') as \"%s\"\n",
_("Description") ); _("Description") );
/* /*
...@@ -214,7 +214,7 @@ describeOperators(const char *name) ...@@ -214,7 +214,7 @@ describeOperators(const char *name)
" CASE WHEN o.oprkind='l' THEN NULL ELSE format_type(o.oprleft, NULL) END AS \"%s\",\n" " CASE WHEN o.oprkind='l' THEN NULL ELSE format_type(o.oprleft, NULL) END AS \"%s\",\n"
" CASE WHEN o.oprkind='r' THEN NULL ELSE format_type(o.oprright, NULL) END AS \"%s\",\n" " CASE WHEN o.oprkind='r' THEN NULL ELSE format_type(o.oprright, NULL) END AS \"%s\",\n"
" format_type(p.prorettype, NULL) AS \"%s\",\n" " format_type(p.prorettype, NULL) AS \"%s\",\n"
" obj_description(p.oid) as \"%s\"\n" " obj_description(p.oid, 'pg_proc') as \"%s\"\n"
"FROM pg_proc p, pg_operator o\n" "FROM pg_proc p, pg_operator o\n"
"WHERE RegprocToOid(o.oprcode) = p.oid\n", "WHERE RegprocToOid(o.oprcode) = p.oid\n",
_("Name"), _("Left arg type"), _("Right arg type"), _("Name"), _("Left arg type"), _("Right arg type"),
...@@ -265,7 +265,7 @@ listAllDbs(bool desc) ...@@ -265,7 +265,7 @@ listAllDbs(bool desc)
#endif #endif
if (desc) if (desc)
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
",\n obj_description(d.oid) as \"%s\"", ",\n obj_description(d.oid, 'pg_database') as \"%s\"",
_("Description")); _("Description"));
strcat(buf, strcat(buf,
"\nFROM pg_database d LEFT JOIN pg_user u ON d.datdba = u.usesysid\n" "\nFROM pg_database d LEFT JOIN pg_user u ON d.datdba = u.usesysid\n"
...@@ -348,28 +348,34 @@ objectDescription(const char *object) ...@@ -348,28 +348,34 @@ objectDescription(const char *object)
"FROM (\n" "FROM (\n"
/* Aggregate descriptions */ /* Aggregate descriptions */
" SELECT a.oid as oid, CAST(a.aggname AS text) as name, CAST('%s' AS text) as object\n" " SELECT a.oid as oid, a.tableoid as tableoid,\n"
" CAST(a.aggname AS text) as name, CAST('%s' AS text) as object\n"
" FROM pg_aggregate a\n" " FROM pg_aggregate a\n"
/* Function descriptions (except in/outs for datatypes) */ /* Function descriptions (except in/outs for datatypes) */
"UNION ALL\n" "UNION ALL\n"
" SELECT p.oid as oid, CAST(p.proname AS text) as name, CAST('%s' AS text) as object\n" " SELECT p.oid as oid, p.tableoid as tableoid,\n"
" CAST(p.proname AS text) as name, CAST('%s' AS text) as object\n"
" FROM pg_proc p\n" " FROM pg_proc p\n"
" WHERE p.pronargs = 0 or oidvectortypes(p.proargtypes) <> ''\n" " WHERE p.pronargs = 0 or oidvectortypes(p.proargtypes) <> ''\n"
/* Operator descriptions (must get comment via associated function) */ /* Operator descriptions (must get comment via associated function) */
"UNION ALL\n" "UNION ALL\n"
" SELECT RegprocToOid(o.oprcode) as oid, CAST(o.oprname AS text) as name, CAST('%s' AS text) as object\n" " SELECT RegprocToOid(o.oprcode) as oid,\n"
" (SELECT oid FROM pg_class WHERE relname = 'pg_proc') as tableoid,\n"
" CAST(o.oprname AS text) as name, CAST('%s' AS text) as object\n"
" FROM pg_operator o\n" " FROM pg_operator o\n"
/* Type description */ /* Type description */
"UNION ALL\n" "UNION ALL\n"
" SELECT t.oid as oid, format_type(t.oid, NULL) as name, CAST('%s' AS text) as object\n" " SELECT t.oid as oid, t.tableoid as tableoid,\n"
" format_type(t.oid, NULL) as name, CAST('%s' AS text) as object\n"
" FROM pg_type t\n" " FROM pg_type t\n"
/* Relation (tables, views, indexes, sequences) descriptions */ /* Relation (tables, views, indexes, sequences) descriptions */
"UNION ALL\n" "UNION ALL\n"
" SELECT c.oid as oid, CAST(c.relname AS text) as name,\n" " SELECT c.oid as oid, c.tableoid as tableoid,\n"
" CAST(c.relname AS text) as name,\n"
" CAST(\n" " CAST(\n"
" CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'i' THEN '%s' WHEN 'S' THEN '%s' END" " CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'i' THEN '%s' WHEN 'S' THEN '%s' END"
" AS text) as object\n" " AS text) as object\n"
...@@ -377,18 +383,20 @@ objectDescription(const char *object) ...@@ -377,18 +383,20 @@ objectDescription(const char *object)
/* Rule description (ignore rules for views) */ /* Rule description (ignore rules for views) */
"UNION ALL\n" "UNION ALL\n"
" SELECT r.oid as oid, CAST(r.rulename AS text) as name, CAST('%s' AS text) as object\n" " SELECT r.oid as oid, r.tableoid as tableoid,\n"
" CAST(r.rulename AS text) as name, CAST('%s' AS text) as object\n"
" FROM pg_rewrite r\n" " FROM pg_rewrite r\n"
" WHERE r.rulename !~ '^_RET'\n" " WHERE r.rulename !~ '^_RET'\n"
/* Trigger description */ /* Trigger description */
"UNION ALL\n" "UNION ALL\n"
" SELECT t.oid as oid, CAST(t.tgname AS text) as name, CAST('%s' AS text) as object\n" " SELECT t.oid as oid, t.tableoid as tableoid,\n"
" CAST(t.tgname AS text) as name, CAST('%s' AS text) as object\n"
" FROM pg_trigger t\n" " FROM pg_trigger t\n"
") AS tt,\n" ") AS tt,\n"
"pg_description d\n" "pg_description d\n"
"WHERE tt.oid = d.objoid\n", "WHERE tt.oid = d.objoid and tt.tableoid = d.classoid and d.objsubid = 0\n",
_("Name"), _("Object"), _("Description"), _("Name"), _("Object"), _("Description"),
_("aggregate"), _("function"), _("operator"), _("aggregate"), _("function"), _("operator"),
...@@ -528,7 +536,7 @@ describeTableDetails(const char *name, bool desc) ...@@ -528,7 +536,7 @@ describeTableDetails(const char *name, bool desc)
/* Get column info */ /* Get column info */
strcpy(buf, "SELECT a.attname, format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, a.attnum"); strcpy(buf, "SELECT a.attname, format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, a.attnum");
if (desc) if (desc)
strcat(buf, ", obj_description(a.oid)"); strcat(buf, ", col_description(a.attrelid, a.attnum)");
strcat(buf, "\nFROM pg_class c, pg_attribute a\n" strcat(buf, "\nFROM pg_class c, pg_attribute a\n"
"WHERE c.relname = '"); "WHERE c.relname = '");
strncat(buf, name, NAMEDATALEN); strncat(buf, name, NAMEDATALEN);
...@@ -1025,7 +1033,7 @@ listTables(const char *infotype, const char *name, bool desc) ...@@ -1025,7 +1033,7 @@ listTables(const char *infotype, const char *name, bool desc)
if (desc) if (desc)
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
",\n obj_description(c.oid) as \"%s\"", ",\n obj_description(c.oid, 'pg_class') as \"%s\"",
_("Description")); _("Description"));
strcat(buf, strcat(buf,
"\nFROM pg_class c LEFT JOIN pg_user u ON c.relowner = u.usesysid\n" "\nFROM pg_class c LEFT JOIN pg_user u ON c.relowner = u.usesysid\n"
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* *
* $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.15 2001/06/02 18:25:18 petere Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.16 2001/08/10 18:57:39 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "large_obj.h" #include "large_obj.h"
...@@ -149,7 +149,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg) ...@@ -149,7 +149,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
{ {
PGresult *res; PGresult *res;
Oid loid; Oid loid;
char buf[1024]; char oidbuf[32];
unsigned int i; unsigned int i;
bool own_transaction = true; bool own_transaction = true;
const char *var = GetVariable(pset.vars, "LO_TRANSACTION"); const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
...@@ -189,23 +189,46 @@ do_lo_import(const char *filename_arg, const char *comment_arg) ...@@ -189,23 +189,46 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
/* insert description if given */ /* insert description if given */
if (comment_arg) if (comment_arg)
{ {
sprintf(buf, "INSERT INTO pg_description VALUES (%u, '", loid); char *cmdbuf;
for (i = 0; i < strlen(comment_arg); i++) char *bufptr;
if (comment_arg[i] == '\'') int slen = strlen(comment_arg);
strcat(buf, "\\'");
else
strncat(buf, &comment_arg[i], 1);
strcat(buf, "')");
if (!(res = PSQLexec(buf))) cmdbuf = malloc(slen * 2 + 256);
if (!cmdbuf)
{
if (own_transaction)
{
res = PQexec(pset.db, "ROLLBACK");
PQclear(res);
}
return false;
}
sprintf(cmdbuf,
"INSERT INTO pg_description VALUES (%u, "
"(SELECT oid FROM pg_class WHERE relname = 'pg_largeobject'),"
" 0, '", loid);
bufptr = cmdbuf + strlen(cmdbuf);
for (i = 0; i < slen; i++)
{
if (comment_arg[i] == '\'' || comment_arg[i] == '\\')
*bufptr++ = '\\';
*bufptr++ = comment_arg[i];
}
strcpy(bufptr, "')");
if (!(res = PSQLexec(cmdbuf)))
{ {
if (own_transaction) if (own_transaction)
{ {
res = PQexec(pset.db, "ROLLBACK"); res = PQexec(pset.db, "ROLLBACK");
PQclear(res); PQclear(res);
} }
free(cmdbuf);
return false; return false;
} }
PQclear(res);
free(cmdbuf);
} }
if (own_transaction) if (own_transaction)
...@@ -221,9 +244,9 @@ do_lo_import(const char *filename_arg, const char *comment_arg) ...@@ -221,9 +244,9 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
} }
fprintf(pset.queryFout, "lo_import %d\n", loid); fprintf(pset.queryFout, "lo_import %u\n", loid);
sprintf(buf, "%u", (unsigned int) loid); sprintf(oidbuf, "%u", loid);
SetVariable(pset.vars, "LASTOID", buf); SetVariable(pset.vars, "LASTOID", oidbuf);
return true; return true;
} }
...@@ -278,7 +301,9 @@ do_lo_unlink(const char *loid_arg) ...@@ -278,7 +301,9 @@ do_lo_unlink(const char *loid_arg)
} }
/* remove the comment as well */ /* remove the comment as well */
sprintf(buf, "DELETE FROM pg_description WHERE objoid = %u", loid); sprintf(buf, "DELETE FROM pg_description WHERE objoid = %u "
"AND classoid = (SELECT oid FROM pg_class WHERE relname = 'pg_largeobject')",
loid);
if (!(res = PSQLexec(buf))) if (!(res = PSQLexec(buf)))
{ {
if (own_transaction) if (own_transaction)
...@@ -322,7 +347,7 @@ do_lo_list(void) ...@@ -322,7 +347,7 @@ do_lo_list(void)
printQueryOpt myopt = pset.popt; printQueryOpt myopt = pset.popt;
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"SELECT loid as \"ID\", obj_description(loid) as \"%s\"\n" "SELECT loid as \"ID\", obj_description(loid, 'pg_largeobject') as \"%s\"\n"
"FROM (SELECT DISTINCT loid FROM pg_largeobject) x\n" "FROM (SELECT DISTINCT loid FROM pg_largeobject) x\n"
"ORDER BY \"ID\"", "ORDER BY \"ID\"",
gettext("Description")); gettext("Description"));
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: transam.h,v 1.36 2001/07/12 04:11:13 tgl Exp $ * $Id: transam.h,v 1.37 2001/08/10 18:57:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -63,11 +63,27 @@ ...@@ -63,11 +63,27 @@
typedef unsigned char XidStatus; /* (2 bits) */ typedef unsigned char XidStatus; /* (2 bits) */
/* ---------- /* ----------
* We reserve the first 16384 object ids for manual assignment. * Object ID (OID) zero is InvalidOid.
* oid's less than this appear in the .bki files. the choice of *
* 16384 is completely arbitrary. * OIDs 1-9999 are reserved for manual assignment (see the files
* in src/include/catalog/).
*
* OIDS 10000-16383 are reserved for assignment by genbki.sh.
*
* OIDs beginning at 16384 are assigned at runtime from the OID
* generator. (The first few of these will be assigned during initdb,
* to objects created after the initial BKI script processing.)
*
* The choices of 10000 and 16384 are completely arbitrary, and can be moved
* if we run low on OIDs in either category. Changing the macros below
* should be sufficient to do this.
*
* NOTE: if the OID generator wraps around, we should skip over OIDs 0-16383
* and resume with 16384. This minimizes the odds of OID conflict, by not
* reassigning OIDs that might have been assigned during initdb.
* ---------- * ----------
*/ */
#define FirstGenBKIObjectId 10000
#define BootstrapObjectIdData 16384 #define BootstrapObjectIdData 16384
/* /*
...@@ -111,7 +127,7 @@ extern void TransBlockNumberSetXidStatus(Relation relation, ...@@ -111,7 +127,7 @@ extern void TransBlockNumberSetXidStatus(Relation relation,
/* in transam/varsup.c */ /* in transam/varsup.c */
extern void GetNewTransactionId(TransactionId *xid); extern void GetNewTransactionId(TransactionId *xid);
extern void ReadNewTransactionId(TransactionId *xid); extern void ReadNewTransactionId(TransactionId *xid);
extern void GetNewObjectId(Oid *oid_return); extern Oid GetNewObjectId(void);
extern void CheckMaxObjectId(Oid assigned_oid); extern void CheckMaxObjectId(Oid assigned_oid);
/* ---------------- /* ----------------
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: bootstrap.h,v 1.22 2001/05/12 01:48:49 petere Exp $ * $Id: bootstrap.h,v 1.23 2001/08/10 18:57:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -47,7 +47,7 @@ extern void boot_openrel(char *name); ...@@ -47,7 +47,7 @@ extern void boot_openrel(char *name);
extern char *LexIDStr(int ident_num); extern char *LexIDStr(int ident_num);
extern void DefineAttr(char *name, char *type, int attnum); extern void DefineAttr(char *name, char *type, int attnum);
extern void InsertOneValue(Oid objectid, char *value, int i); extern void InsertOneValue(char *value, int i);
extern void InsertOneNull(int i); extern void InsertOneNull(int i);
extern char *MapArrayTypeName(char *s); extern char *MapArrayTypeName(char *s);
extern char *CleanUpStr(char *s); extern char *CleanUpStr(char *s);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.86 2001/07/15 22:48:18 tgl Exp $ * $Id: catversion.h,v 1.87 2001/08/10 18:57:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200107151 #define CATALOG_VERSION_NO 200108101
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: heap.h,v 1.36 2001/05/30 12:57:36 momjian Exp $ * $Id: heap.h,v 1.37 2001/08/10 18:57:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,7 +33,7 @@ extern Relation heap_create(char *relname, TupleDesc tupDesc, ...@@ -33,7 +33,7 @@ extern Relation heap_create(char *relname, TupleDesc tupDesc,
extern void heap_storage_create(Relation rel); extern void heap_storage_create(Relation rel);
extern Oid heap_create_with_catalog(char *relname, TupleDesc tupdesc, extern Oid heap_create_with_catalog(char *relname, TupleDesc tupdesc,
char relkind, bool istemp, char relkind, bool relhasoids, bool istemp,
bool allow_system_table_mods); bool allow_system_table_mods);
extern void heap_drop_with_catalog(const char *relname, extern void heap_drop_with_catalog(const char *relname,
...@@ -48,6 +48,7 @@ extern void AddRelationRawConstraints(Relation rel, ...@@ -48,6 +48,7 @@ extern void AddRelationRawConstraints(Relation rel,
extern int RemoveCheckConstraint(Relation rel, const char *constrName, bool inh); extern int RemoveCheckConstraint(Relation rel, const char *constrName, bool inh);
extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno); extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
bool relhasoids);
#endif /* HEAP_H */ #endif /* HEAP_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: index.h,v 1.37 2001/07/16 05:06:59 tgl Exp $ * $Id: index.h,v 1.38 2001/08/10 18:57:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -34,7 +34,7 @@ extern void InitIndexStrategy(int numatts, ...@@ -34,7 +34,7 @@ extern void InitIndexStrategy(int numatts,
Relation indexRelation, Relation indexRelation,
Oid accessMethodObjectId); Oid accessMethodObjectId);
extern void index_create(char *heapRelationName, extern Oid index_create(char *heapRelationName,
char *indexRelationName, char *indexRelationName,
IndexInfo *indexInfo, IndexInfo *indexInfo,
Oid accessMethodObjectId, Oid accessMethodObjectId,
...@@ -56,7 +56,8 @@ extern void FormIndexDatum(IndexInfo *indexInfo, ...@@ -56,7 +56,8 @@ extern void FormIndexDatum(IndexInfo *indexInfo,
extern void UpdateStats(Oid relid, double reltuples); extern void UpdateStats(Oid relid, double reltuples);
extern bool IndexesAreActive(Oid relid, bool comfirmCommitted); extern bool IndexesAreActive(Oid relid, bool comfirmCommitted);
extern void setRelhasindex(Oid relid, bool hasindex); extern void setRelhasindex(Oid relid, bool hasindex,
bool isprimary, Oid reltoastidxid);
extern void setNewRelfilenode(Relation relation); extern void setNewRelfilenode(Relation relation);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: indexing.h,v 1.51 2001/06/16 18:59:31 tgl Exp $ * $Id: indexing.h,v 1.52 2001/08/10 18:57:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
/* /*
* Number of indices that exist for each system catalog * Number of indices that exist for each system catalog
*/ */
#define Num_pg_aggregate_indices 1 #define Num_pg_aggregate_indices 2
#define Num_pg_am_indices 2 #define Num_pg_am_indices 2
#define Num_pg_amop_indices 2 #define Num_pg_amop_indices 2
#define Num_pg_amproc_indices 1 #define Num_pg_amproc_indices 1
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#define AccessMethodStrategyIndex "pg_amop_strategy_index" #define AccessMethodStrategyIndex "pg_amop_strategy_index"
#define AccessProcedureIndex "pg_amproc_am_opcl_procnum_index" #define AccessProcedureIndex "pg_amproc_am_opcl_procnum_index"
#define AggregateNameTypeIndex "pg_aggregate_name_type_index" #define AggregateNameTypeIndex "pg_aggregate_name_type_index"
#define AggregateOidIndex "pg_aggregate_oid_index"
#define AmNameIndex "pg_am_name_index" #define AmNameIndex "pg_am_name_index"
#define AmOidIndex "pg_am_oid_index" #define AmOidIndex "pg_am_oid_index"
#define AttrDefaultIndex "pg_attrdef_adrelid_adnum_index" #define AttrDefaultIndex "pg_attrdef_adrelid_adnum_index"
...@@ -60,7 +61,7 @@ ...@@ -60,7 +61,7 @@
#define ClassOidIndex "pg_class_oid_index" #define ClassOidIndex "pg_class_oid_index"
#define DatabaseNameIndex "pg_database_datname_index" #define DatabaseNameIndex "pg_database_datname_index"
#define DatabaseOidIndex "pg_database_oid_index" #define DatabaseOidIndex "pg_database_oid_index"
#define DescriptionObjIndex "pg_description_objoid_index" #define DescriptionObjIndex "pg_description_o_c_o_index"
#define GroupNameIndex "pg_group_name_index" #define GroupNameIndex "pg_group_name_index"
#define GroupSysidIndex "pg_group_sysid_index" #define GroupSysidIndex "pg_group_sysid_index"
#define IndexIndrelidIndex "pg_index_indrelid_index" #define IndexIndrelidIndex "pg_index_indrelid_index"
...@@ -151,6 +152,7 @@ extern HeapTuple ClassOidIndexScan(Relation heapRelation, Datum relId); ...@@ -151,6 +152,7 @@ extern HeapTuple ClassOidIndexScan(Relation heapRelation, Datum relId);
*/ */
DECLARE_UNIQUE_INDEX(pg_aggregate_name_type_index on pg_aggregate using btree(aggname name_ops, aggbasetype oid_ops)); DECLARE_UNIQUE_INDEX(pg_aggregate_name_type_index on pg_aggregate using btree(aggname name_ops, aggbasetype oid_ops));
DECLARE_UNIQUE_INDEX(pg_aggregate_oid_index on pg_aggregate using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops)); DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops));
DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_amop_opid_index on pg_amop using btree(amopclaid oid_ops, amopopr oid_ops, amopid oid_ops)); DECLARE_UNIQUE_INDEX(pg_amop_opid_index on pg_amop using btree(amopclaid oid_ops, amopopr oid_ops, amopid oid_ops));
...@@ -163,7 +165,7 @@ DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops)); ...@@ -163,7 +165,7 @@ DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_class_relname_index on pg_class using btree(relname name_ops)); DECLARE_UNIQUE_INDEX(pg_class_relname_index on pg_class using btree(relname name_ops));
DECLARE_UNIQUE_INDEX(pg_database_datname_index on pg_database using btree(datname name_ops)); DECLARE_UNIQUE_INDEX(pg_database_datname_index on pg_database using btree(datname name_ops));
DECLARE_UNIQUE_INDEX(pg_database_oid_index on pg_database using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_database_oid_index on pg_database using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_description_objoid_index on pg_description using btree(objoid oid_ops)); DECLARE_UNIQUE_INDEX(pg_description_o_c_o_index on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops));
DECLARE_UNIQUE_INDEX(pg_group_name_index on pg_group using btree(groname name_ops)); DECLARE_UNIQUE_INDEX(pg_group_name_index on pg_group using btree(groname name_ops));
DECLARE_UNIQUE_INDEX(pg_group_sysid_index on pg_group using btree(grosysid int4_ops)); DECLARE_UNIQUE_INDEX(pg_group_sysid_index on pg_group using btree(grosysid int4_ops));
/* This following index is not used for a cache and is not unique */ /* This following index is not used for a cache and is not unique */
......
This diff is collapsed.
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_amproc.h,v 1.27 2001/01/24 19:43:20 momjian Exp $ * $Id: pg_amproc.h,v 1.28 2001/08/10 18:57:39 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
* typedef struct FormData_pg_amproc * typedef struct FormData_pg_amproc
* ---------------- * ----------------
*/ */
CATALOG(pg_amproc) CATALOG(pg_amproc) BKI_WITHOUT_OIDS
{ {
Oid amid; /* the access method this proc is for */ Oid amid; /* the access method this proc is for */
Oid amopclaid; /* the opclass this proc is for */ Oid amopclaid; /* the opclass this proc is for */
...@@ -64,65 +64,65 @@ typedef FormData_pg_amproc *Form_pg_amproc; ...@@ -64,65 +64,65 @@ typedef FormData_pg_amproc *Form_pg_amproc;
*/ */
/* rtree */ /* rtree */
DATA(insert OID = 0 (402 422 193 1)); DATA(insert (402 422 193 1));
DATA(insert OID = 0 (402 422 194 2)); DATA(insert (402 422 194 2));
DATA(insert OID = 0 (402 422 195 3)); DATA(insert (402 422 195 3));
DATA(insert OID = 0 (402 433 193 1)); DATA(insert (402 433 193 1));
DATA(insert OID = 0 (402 433 194 2)); DATA(insert (402 433 194 2));
DATA(insert OID = 0 (402 433 196 3)); DATA(insert (402 433 196 3));
DATA(insert OID = 0 (402 434 197 1)); DATA(insert (402 434 197 1));
DATA(insert OID = 0 (402 434 198 2)); DATA(insert (402 434 198 2));
DATA(insert OID = 0 (402 434 199 3)); DATA(insert (402 434 199 3));
/* btree */ /* btree */
DATA(insert OID = 0 (403 421 350 1)); DATA(insert (403 421 350 1));
DATA(insert OID = 0 (403 423 355 1)); DATA(insert (403 423 355 1));
DATA(insert OID = 0 (403 426 351 1)); DATA(insert (403 426 351 1));
DATA(insert OID = 0 (403 427 356 1)); DATA(insert (403 427 356 1));
DATA(insert OID = 0 (403 428 354 1)); DATA(insert (403 428 354 1));
DATA(insert OID = 0 (403 429 358 1)); DATA(insert (403 429 358 1));
DATA(insert OID = 0 (403 431 360 1)); DATA(insert (403 431 360 1));
DATA(insert OID = 0 (403 432 357 1)); DATA(insert (403 432 357 1));
DATA(insert OID = 0 (403 435 404 1)); DATA(insert (403 435 404 1));
DATA(insert OID = 0 (403 754 842 1)); DATA(insert (403 754 842 1));
DATA(insert OID = 0 (403 1076 1078 1)); DATA(insert (403 1076 1078 1));
DATA(insert OID = 0 (403 1077 1079 1)); DATA(insert (403 1077 1079 1));
DATA(insert OID = 0 (403 1114 1092 1)); DATA(insert (403 1114 1092 1));
DATA(insert OID = 0 (403 1115 1107 1)); DATA(insert (403 1115 1107 1));
DATA(insert OID = 0 (403 1181 359 1)); DATA(insert (403 1181 359 1));
DATA(insert OID = 0 (403 1312 1314 1)); DATA(insert (403 1312 1314 1));
DATA(insert OID = 0 (403 1313 1315 1)); DATA(insert (403 1313 1315 1));
DATA(insert OID = 0 (403 810 836 1)); DATA(insert (403 810 836 1));
DATA(insert OID = 0 (403 935 926 1)); DATA(insert (403 935 926 1));
DATA(insert OID = 0 (403 652 926 1)); DATA(insert (403 652 926 1));
DATA(insert OID = 0 (403 1768 1769 1)); DATA(insert (403 1768 1769 1));
DATA(insert OID = 0 (403 1690 1693 1)); DATA(insert (403 1690 1693 1));
DATA(insert OID = 0 (403 1399 1358 1)); DATA(insert (403 1399 1358 1));
DATA(insert OID = 0 (403 424 1596 1)); DATA(insert (403 424 1596 1));
DATA(insert OID = 0 (403 425 1672 1)); DATA(insert (403 425 1672 1));
/* hash */ /* hash */
DATA(insert OID = 0 (405 421 449 1)); DATA(insert (405 421 449 1));
DATA(insert OID = 0 (405 423 452 1)); DATA(insert (405 423 452 1));
DATA(insert OID = 0 (405 426 450 1)); DATA(insert (405 426 450 1));
DATA(insert OID = 0 (405 427 453 1)); DATA(insert (405 427 453 1));
DATA(insert OID = 0 (405 428 451 1)); DATA(insert (405 428 451 1));
DATA(insert OID = 0 (405 429 454 1)); DATA(insert (405 429 454 1));
DATA(insert OID = 0 (405 431 456 1)); DATA(insert (405 431 456 1));
DATA(insert OID = 0 (405 435 457 1)); DATA(insert (405 435 457 1));
DATA(insert OID = 0 (405 652 456 1)); DATA(insert (405 652 456 1));
DATA(insert OID = 0 (405 754 949 1)); DATA(insert (405 754 949 1));
DATA(insert OID = 0 (405 810 399 1)); DATA(insert (405 810 399 1));
DATA(insert OID = 0 (405 935 456 1)); DATA(insert (405 935 456 1));
DATA(insert OID = 0 (405 1076 1080 1)); DATA(insert (405 1076 1080 1));
DATA(insert OID = 0 (405 1077 456 1)); DATA(insert (405 1077 456 1));
DATA(insert OID = 0 (405 1114 450 1)); DATA(insert (405 1114 450 1));
DATA(insert OID = 0 (405 1115 452 1)); DATA(insert (405 1115 452 1));
DATA(insert OID = 0 (405 1181 455 1)); DATA(insert (405 1181 455 1));
DATA(insert OID = 0 (405 1312 452 1)); DATA(insert (405 1312 452 1));
DATA(insert OID = 0 (405 1313 1697 1)); DATA(insert (405 1313 1697 1));
DATA(insert OID = 0 (405 1399 1696 1)); DATA(insert (405 1399 1696 1));
#endif /* PG_AMPROC_H */ #endif /* PG_AMPROC_H */
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* typedef struct FormData_pg_attrdef * typedef struct FormData_pg_attrdef
* ---------------- * ----------------
*/ */
CATALOG(pg_attrdef) CATALOG(pg_attrdef) BKI_WITHOUT_OIDS
{ {
Oid adrelid; Oid adrelid;
int2 adnum; int2 adnum;
......
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.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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