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 @@
-- darcy@druid.net
-- 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
-- %%PGDIR%% changed to your local directory where modules is
--
......@@ -73,9 +73,7 @@ create operator <> (
procedure = ne
);
INSERT INTO pg_description (objoid, description)
SELECT oid, 'password type with checks'
FROM pg_type WHERE typname = 'chkpass';
COMMENT ON TYPE chkpass IS 'password type with checks';
--
-- eof
......
......@@ -9,10 +9,10 @@ it on anything but an empty database, such as template1.
Uses pgeasy library.
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 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
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.
(Ideally we'd just regenerate the script as part of the regression
tests themselves, but that seems too slow...)
NOTE: in 7.1, make_oidjoins_check produces two bogus join checks, one for
pg_database.datlastsysoid => pg_description.oid and one for
pg_class.relfilenode => pg_class.oid. These are artifacts and should not
NOTE: in 7.2, make_oidjoins_check produces one bogus join check, for
pg_class.relfilenode => pg_class.oid. This is an artifact and should not
be added to the oidjoins regress test.
---------------------------------------------------------------------------
......@@ -41,13 +40,13 @@ Join pg_aggregate.aggtranstype => pg_type.oid
Join pg_aggregate.aggfinaltype => pg_type.oid
Join pg_am.amgettuple => 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.amrescan => pg_proc.oid
Join pg_am.amendscan => pg_proc.oid
Join pg_am.ammarkpos => pg_proc.oid
Join pg_am.amrestrpos => 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_amop.amopid => pg_am.oid
Join pg_amop.amopclaid => pg_opclass.oid
......@@ -61,6 +60,7 @@ Join pg_class.reltype => pg_type.oid
Join pg_class.relam => pg_am.oid
Join pg_class.reltoastrelid => 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.indrelid => pg_class.oid
Join pg_opclass.opcdeftype => pg_type.oid
......@@ -78,7 +78,9 @@ Join pg_proc.prolang => pg_language.oid
Join pg_proc.prorettype => pg_type.oid
Join pg_rewrite.ev_class => 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.tgfoid => pg_proc.oid
Join pg_type.typrelid => pg_class.oid
......
......@@ -38,7 +38,6 @@ main(int argc, char **argv)
FROM pg_class c, pg_attribute a, pg_type t \
WHERE a.attnum > 0 AND \
relkind = 'r' AND \
relhasrules = 'f' AND \
(typname = 'oid' OR \
typname = 'regproc') AND \
a.attrelid = c.oid AND \
......@@ -52,8 +51,7 @@ main(int argc, char **argv)
DECLARE c_relations BINARY CURSOR FOR \
SELECT relname \
FROM pg_class c \
WHERE relkind = 'r' AND \
relhasrules = 'f' \
WHERE relkind = 'r' AND relhasoids \
ORDER BY 1; \
");
doquery("FETCH ALL IN c_relations");
......@@ -71,14 +69,14 @@ main(int argc, char **argv)
sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*) \
FROM %s t1, %s t2 \
WHERE t1.%s = t2.oid ", relname, relname2, attname);
FROM \"%s\" t1, \"%s\" t2 \
WHERE t1.\"%s\" = t2.oid ", relname, relname2, attname);
else
sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*) \
FROM %s t1, %s t2 \
WHERE RegprocToOid(t1.%s) = t2.oid ", relname, relname2, attname);
FROM \"%s\" t1, \"%s\" t2 \
WHERE RegprocToOid(t1.\"%s\") = t2.oid ", relname, relname2, attname);
doquery(query);
doquery("FETCH ALL IN c_matches");
......
#! /bin/sh
# 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
# will NOT be checked by the output of this script. You should be
......@@ -41,7 +41,7 @@ $AWK -F'[ \.]' '\
}
{
printf "\
SELECT oid, %s.%s \n\
SELECT ctid, %s.%s \n\
FROM %s \n\
WHERE %s.%s != 0 AND \n\
NOT EXISTS(SELECT * FROM %s AS t1 WHERE t1.oid = %s.%s);\n",
......
......@@ -11,42 +11,27 @@ BEGIN TRANSACTION;
CREATE FUNCTION _int_contains(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description)
SELECT oid, 'contains'::text
FROM pg_proc
WHERE proname = '_int_contains'::name;
COMMENT ON FUNCTION _int_contains(_int4, _int4) IS 'contains';
CREATE FUNCTION _int_contained(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description)
SELECT oid, 'contained in'::text
FROM pg_proc
WHERE proname = '_int_contained'::name;
COMMENT ON FUNCTION _int_contained(_int4, _int4) IS 'contained in';
CREATE FUNCTION _int_overlap(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description)
SELECT oid, 'overlaps'::text
FROM pg_proc
WHERE proname = '_int_overlap'::name;
COMMENT ON FUNCTION _int_overlap(_int4, _int4) IS 'overlaps';
CREATE FUNCTION _int_same(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description)
SELECT oid, 'same as'::text
FROM pg_proc
WHERE proname = '_int_same'::name;
COMMENT ON FUNCTION _int_same(_int4, _int4) IS 'same as';
CREATE FUNCTION _int_different(_int4, _int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
INSERT INTO pg_description (objoid, description)
SELECT oid, 'different'::text
FROM pg_proc
WHERE proname = '_int_different'::name;
COMMENT ON FUNCTION _int_different(_int4, _int4) IS 'different';
-- support routines for indexing
......
<!--
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">
......@@ -532,9 +532,9 @@
<para>
<structname>pg_class</structname> catalogues tables and mostly
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
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
fields are meaningful for all relation types.
</para>
......@@ -565,8 +565,8 @@
<entry><type>oid</type></entry>
<entry>pg_type.oid</entry>
<entry>
The data type that corresponds to this table (not functional,
only set for system tables)
The OID of the data type that corresponds to this table, if any
(zero for indexes, which have no pg_type entry)
</entry>
</row>
......@@ -631,14 +631,19 @@
<entry>reltoastidxid</entry>
<entry><type>oid</type></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>
<entry>relhasindex</entry>
<entry><type>bool</type></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>
......@@ -664,7 +669,7 @@
<entry><type>int2</type></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
<structname>pg_attribute</structname>. See also
<structname>pg_attribute</structname>.<structfield>attnum</structfield>.
......@@ -695,14 +700,30 @@
<entry>relukeys</entry>
<entry><type>int2</type></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>
<entry>relfkeys</entry>
<entry><type>int2</type></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>
......@@ -710,8 +731,7 @@
<entry><type>bool</type></entry>
<entry></entry>
<entry>
unused (No, this does not say whether the table has a primary
key. It's really unused.)
True if the table has (or once had) a primary key.
</entry>
</row>
......@@ -726,7 +746,7 @@
<entry>relhassubclass</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>At least one table inherits this one</entry>
<entry>At least one table inherits from this one</entry>
</row>
<row>
......@@ -874,6 +894,23 @@
<entry>The oid of the object this description pertains to</entry>
</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>
<entry>description</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
-->
......@@ -25,8 +25,9 @@ Postgres documentation
<synopsis>
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>table_constraint</replaceable> } [, ... ]
) [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
| <replaceable>table_constraint</replaceable> } [, ... ] )
[ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ]
where <replaceable class="PARAMETER">column_constraint</replaceable> can be:
[ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
......@@ -108,6 +109,18 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> can be:
</listitem>
</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>
<term><replaceable class="PARAMETER">constraint_name</replaceable></term>
<listitem>
......@@ -303,6 +316,49 @@ INHERITS ( <replaceable class="PARAMETER">parent_table</replaceable> [, ... ] )
</para>
</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">
<title id="R1-SQL-DEFAULTCLAUSE-1-TITLE">
DEFAULT Clause
......@@ -2098,6 +2154,18 @@ ALTER DOMAIN cities
supported by <productname>Postgres</productname>.
</para>
</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>
</refsect1>
</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">
......@@ -641,8 +641,9 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
<primary>OID</primary>
</indexterm>
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
reused and are 32-bit quantities.
that is automatically added by Postgres to all table rows (unless
the table was created WITHOUT OIDS, in which case this column is
not present).
</para>
</listitem>
</varlistentry>
......@@ -686,8 +687,10 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
<listitem>
<para>
The identity (transaction ID) of the deleting transaction,
or zero for an undeleted tuple. In practice, this is never nonzero
for a visible tuple.
or zero for an undeleted tuple. It is possible for this field
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>
</listitem>
</varlistentry>
......@@ -697,7 +700,6 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
<listitem>
<para>
The command identifier within the deleting transaction, or zero.
Again, this is never nonzero for a visible tuple.
</para>
</listitem>
</varlistentry>
......@@ -720,10 +722,27 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
</variablelist>
</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>
For further information on the system attributes consult
<xref linkend="STON87a" endterm="STON87a">.
Transaction and command identifiers are 32-bit quantities.
</para>
</sect1>
......
......@@ -8,7 +8,7 @@
*
*
* 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
......@@ -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
* 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
......@@ -1049,6 +1042,8 @@ heap_insert(Relation relation, HeapTuple tup)
IncrHeapAccessStat(local_insert);
IncrHeapAccessStat(global_insert);
if (relation->rd_rel->relhasoids)
{
/*
* 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
......@@ -1061,6 +1056,7 @@ heap_insert(Relation relation, HeapTuple tup)
tup->t_data->t_oid = newoid();
else
CheckMaxObjectId(tup->t_data->t_oid);
}
TransactionIdStore(GetCurrentTransactionId(), &(tup->t_data->t_xmin));
tup->t_data->t_cmin = GetCurrentCommandId();
......
......@@ -8,7 +8,7 @@
*
*
* 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
......@@ -45,7 +45,7 @@ static void toast_delete(Relation rel, HeapTuple oldtup);
static void toast_delete_datum(Relation rel, Datum value);
static void toast_insert_or_update(Relation rel, HeapTuple newtup,
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);
......@@ -319,10 +319,10 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
VARATT_IS_EXTERNAL(old_value))
{
if (new_isnull || !VARATT_IS_EXTERNAL(new_value) ||
old_value->va_content.va_external.va_rowid !=
new_value->va_content.va_external.va_rowid ||
old_value->va_content.va_external.va_attno !=
new_value->va_content.va_external.va_attno)
old_value->va_content.va_external.va_valueid !=
new_value->va_content.va_external.va_valueid ||
old_value->va_content.va_external.va_toastrelid !=
new_value->va_content.va_external.va_toastrelid)
{
/*
......@@ -524,10 +524,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
i = biggest_attno;
old_value = toast_values[i];
toast_action[i] = 'p';
toast_values[i] = toast_save_datum(rel,
newtup->t_data->t_oid,
i + 1,
toast_values[i]);
toast_values[i] = toast_save_datum(rel, toast_values[i]);
if (toast_free[i])
pfree(DatumGetPointer(old_value));
......@@ -639,10 +636,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
i = biggest_attno;
old_value = toast_values[i];
toast_action[i] = 'p';
toast_values[i] = toast_save_datum(rel,
newtup->t_data->t_oid,
i + 1,
toast_values[i]);
toast_values[i] = toast_save_datum(rel, toast_values[i]);
if (toast_free[i])
pfree(DatumGetPointer(old_value));
......@@ -772,7 +766,7 @@ toast_compress_datum(Datum value)
* ----------
*/
static Datum
toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
toast_save_datum(Relation rel, Datum value)
{
Relation toastrel;
Relation toastidx;
......@@ -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_toastrelid =
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
......@@ -836,21 +826,20 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
*/
toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
toasttupDesc = toastrel->rd_att;
toastidx = index_open(rel->rd_rel->reltoastidxid);
toastidx = index_open(toastrel->rd_rel->reltoastidxid);
/*
* Split up the item into chunks
*/
while (data_todo > 0)
{
/*
* Calculate the size of this chunk
*/
chunk_size = Min(TOAST_MAX_CHUNK_SIZE, data_todo);
/*
* Build a tuple
* Build a tuple and store it
*/
t_values[1] = Int32GetDatum(chunk_seq++);
VARATT_SIZEP(&chunk_data) = chunk_size + VARHDRSZ;
......@@ -859,10 +848,16 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
if (!HeapTupleIsValid(toasttup))
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,
&(toasttup->t_self),
toastrel);
......@@ -872,8 +867,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
/*
* Free memory
*/
heap_freetuple(toasttup);
pfree(idxres);
heap_freetuple(toasttup);
/*
* Move on to next chunk
......@@ -918,10 +913,11 @@ toast_delete_datum(Relation rel, Datum value)
*/
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
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
* (we don't particularly care whether we see them in sequence or not)
*/
ScanKeyEntryInitialize(&toastkey,
(bits16) 0,
......@@ -930,7 +926,7 @@ toast_delete_datum(Relation rel, Datum value)
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);
while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
......@@ -1009,7 +1005,7 @@ toast_fetch_datum(varattrib *attr)
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
AccessShareLock);
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
......@@ -1049,25 +1045,25 @@ toast_fetch_datum(varattrib *attr)
* Some checks on the data we've found
*/
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,
attr->va_content.va_external.va_valueid);
if (residx < numchunks - 1)
{
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,
attr->va_content.va_external.va_valueid);
}
else
{
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,
attr->va_content.va_external.va_valueid);
}
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,
attr->va_content.va_external.va_valueid);
......@@ -1085,7 +1081,7 @@ toast_fetch_datum(varattrib *attr)
* Final checks that we successfully fetched the datum
*/
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);
pfree(chunks_expected);
pfree(chunks_found);
......
......@@ -6,7 +6,7 @@
* Copyright (c) 2000, PostgreSQL Global Development Group
*
* 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)
static Oid lastSeenOid = InvalidOid;
void
GetNewObjectId(Oid *oid_return)
Oid
GetNewObjectId(void)
{
Oid result;
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 (ShmemVariableCache->oidCount == 0)
{
......@@ -117,13 +132,16 @@ GetNewObjectId(Oid *oid_return)
ShmemVariableCache->oidCount = VAR_OID_PREFETCH;
}
if (PointerIsValid(oid_return))
lastSeenOid = (*oid_return) = ShmemVariableCache->nextOid;
result = ShmemVariableCache->nextOid;
(ShmemVariableCache->nextOid)++;
(ShmemVariableCache->oidCount)--;
SpinRelease(OidGenLockId);
lastSeenOid = result;
return result;
}
void
......@@ -159,8 +177,8 @@ CheckMaxObjectId(Oid assigned_oid)
*/
XLogPutNextOid(assigned_oid + VAR_OID_PREFETCH);
ShmemVariableCache->oidCount = VAR_OID_PREFETCH - 1;
ShmemVariableCache->nextOid = assigned_oid + 1;
ShmemVariableCache->oidCount = VAR_OID_PREFETCH - 1;
SpinRelease(OidGenLockId);
}
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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)
checkPoint.nextXid, checkPoint.nextOid);
if (checkPoint.nextXid < FirstTransactionId)
elog(STOP, "invalid next transaction id");
if (checkPoint.nextOid < BootstrapObjectIdData)
elog(STOP, "invalid next oid");
ShmemVariableCache->nextXid = checkPoint.nextXid;
ShmemVariableCache->nextOid = checkPoint.nextOid;
......
......@@ -9,7 +9,7 @@
*
*
* 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()
int num_columns_read = 0;
static Oid objectid;
%}
......@@ -91,7 +90,7 @@ static Oid objectid;
%type <list> boot_index_params
%type <ielem> boot_index_param
%type <ival> boot_const boot_ident
%type <ival> optbootstrap boot_tuple boot_tuplelist
%type <ival> optbootstrap optwithoutoids boot_tuple boot_tuplelist
%type <oidval> optoideq
%token <ival> CONST ID
......@@ -99,7 +98,7 @@ static Oid objectid;
%token STRING XDEFINE
%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE
%token COMMA EQUALS LPAREN RPAREN
%token OBJ_ID XBOOTSTRAP NULLVAL
%token OBJ_ID XBOOTSTRAP XWITHOUT_OIDS NULLVAL
%start TopLevel
%nonassoc low
......@@ -152,7 +151,7 @@ Boot_CloseStmt:
;
Boot_CreateStmt:
XCREATE optbootstrap boot_ident LPAREN
XCREATE optbootstrap optwithoutoids boot_ident LPAREN
{
do_start();
numattr = 0;
......@@ -160,10 +159,10 @@ Boot_CreateStmt:
{
if ($2)
elog(DEBUG, "creating bootstrap relation %s...",
LexIDStr($3));
LexIDStr($4));
else
elog(DEBUG, "creating relation %s...",
LexIDStr($3));
LexIDStr($4));
}
}
boot_typelist
......@@ -185,9 +184,10 @@ Boot_CreateStmt:
closerel(NULL);
}
tupdesc = CreateTupleDesc(numattr,attrtypes);
reldesc = heap_create(LexIDStr($3), tupdesc,
tupdesc = CreateTupleDesc(numattr, attrtypes);
reldesc = heap_create(LexIDStr($4), tupdesc,
false, true, true);
reldesc->rd_rel->relhasoids = ! ($3);
if (DebugMode)
elog(DEBUG, "bootstrap relation created");
}
......@@ -197,9 +197,10 @@ Boot_CreateStmt:
TupleDesc tupdesc;
tupdesc = CreateTupleDesc(numattr,attrtypes);
id = heap_create_with_catalog(LexIDStr($3),
id = heap_create_with_catalog(LexIDStr($4),
tupdesc,
RELKIND_RELATION,
! ($3),
false,
true);
if (DebugMode)
......@@ -232,8 +233,7 @@ Boot_InsertStmt:
elog(ERROR, "relation not open");
err_out();
}
objectid = $2;
InsertOneTuple(objectid);
InsertOneTuple($2);
do_end();
}
;
......@@ -287,6 +287,11 @@ optbootstrap:
| { $$ = 0; }
;
optwithoutoids:
XWITHOUT_OIDS { $$ = 1; }
| { $$ = 0; }
;
boot_typelist:
boot_type_thing
| boot_typelist COMMA boot_type_thing
......@@ -303,7 +308,7 @@ boot_type_thing:
optoideq:
OBJ_ID EQUALS boot_ident { $$ = atol(LexIDStr($3)); }
| { $$ = newoid(); }
| { $$ = (Oid) 0; }
;
boot_tuplelist:
......@@ -313,8 +318,10 @@ boot_tuplelist:
;
boot_tuple:
boot_ident {InsertOneValue(objectid, LexIDStr($1), num_columns_read++); }
| boot_const {InsertOneValue(objectid, LexIDStr($1), num_columns_read++); }
boot_ident
{ InsertOneValue(LexIDStr($1), num_columns_read++); }
| boot_const
{ InsertOneValue(LexIDStr($1), num_columns_read++); }
| NULLVAL
{ InsertOneNull(num_columns_read++); }
;
......
......@@ -9,7 +9,7 @@
*
*
* 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); }
"index" { return(INDEX); }
"on" { return(ON); }
"using" { return(USING); }
"without_oids" { return(XWITHOUT_OIDS); }
{arrayid} {
yylval.ival = EnterString(MapArrayTypeName((char*)yytext));
return(ID);
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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)
/* ----------------
* 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
......@@ -635,7 +637,6 @@ InsertOneTuple(Oid objectid)
{
HeapTuple tuple;
TupleDesc tupDesc;
int i;
if (DebugMode)
......@@ -664,7 +665,7 @@ InsertOneTuple(Oid objectid)
* ----------------
*/
void
InsertOneValue(Oid objectid, char *value, int i)
InsertOneValue(char *value, int i)
{
int typeindex;
char *prt;
......
......@@ -8,7 +8,7 @@
*
*
* 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)
* newoid - returns a unique identifier across all catalogs.
*
* Object Id allocation is now done by GetNewObjectID in
* access/transam/varsup.c. oids are now allocated correctly.
* access/transam/varsup.
*
* old comments:
* This needs to change soon, it fails if there are too many more
* 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.
* This code probably needs to change to generate OIDs separately
* for each table.
*/
Oid
newoid(void)
{
Oid lastoid;
GetNewObjectId(&lastoid);
if (!OidIsValid(lastoid))
elog(ERROR, "newoid: GetNewObjectId returns invalid oid");
return lastoid;
return GetNewObjectId();
}
......@@ -10,7 +10,7 @@
#
#
# 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
# non-essential whitespace is removed from the generated file.
......@@ -136,6 +136,15 @@ for dir in $INCLUDE_DIRS; do
fi
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,
# and don't read it separately from config.h. This is OK because both of them
# must be equal to the length of oidvector.
......@@ -184,16 +193,21 @@ sed -e "s/;[ ]*$//g" \
# nc is the number of catalogs
# inside is a variable set to 1 when we are scanning the
# 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)
# nextbkioid is the next OID available for automatic assignment.
# oid is the most recently seen or assigned oid.
# ----------------
BEGIN {
inside = 0;
raw = 0;
bootstrap = 0;
bootstrap = "";
without_oids = "";
nc = 0;
reln_open = 0;
comment_level = 0;
nextbkioid = ENVIRON["BKIOBJECTID"];
oid = 0;
}
# ----------------
......@@ -217,23 +231,26 @@ comment_level > 0 { next; }
raw == 1 { print; next; }
# ----------------
# DATA() statements should get passed right through after
# stripping off the DATA( and the ) on the end.
# DATA() statements are basically passed right through after
# 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 = substr($0, 6, length($0) - 6);
print data;
nf = 1;
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);
break;
oid = nextbkioid;
nextbkioid++;
sub("OID *= *0", "OID = " oid, data);
}
nf++;
}
print data;
next;
}
......@@ -242,7 +259,7 @@ raw == 1 { print; next; }
{
data = substr($0, 8, length($0) - 9);
if (data != "")
printf "%d %s\n", oid, data >>descriptionfile;
printf "%d\t%s\t0\t%s\n", oid, catalog, data >>descriptionfile;
}
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,")");
catalog = substr($1,9,pos-9);
if ($0 ~ /BOOTSTRAP/) {
bootstrap = 1;
bootstrap = "bootstrap ";
}
if ($0 ~ /BKI_WITHOUT_OIDS/) {
without_oids = "without_oids ";
}
i = 1;
......@@ -323,11 +343,7 @@ inside == 1 {
# if this is the last line, then output the bki catalog stuff.
# ----
if ($1 ~ /}/) {
if (bootstrap) {
print "create bootstrap " catalog;
} else {
print "create " catalog;
}
print "create " bootstrap without_oids catalog;
print "\t(";
for (j=1; j<i-1; j++) {
......@@ -336,14 +352,15 @@ inside == 1 {
print "\t " attname[ j ] " = " atttype[ j ] ;
print "\t)";
if (! bootstrap) {
if (bootstrap == "") {
print "open " catalog;
}
i = 1;
reln_open = 1;
inside = 0;
bootstrap = 0;
bootstrap = "";
without_oids = "";
next;
}
......
......@@ -8,7 +8,7 @@
*
*
* 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
......@@ -64,8 +64,10 @@
static void AddNewRelationTuple(Relation pg_class_desc,
Relation new_rel_desc, Oid new_rel_oid, Oid new_type_oid,
int natts, char relkind, char *temp_relname);
Relation new_rel_desc,
Oid new_rel_oid, Oid new_type_oid,
char relkind, bool relhasoids,
char *temp_relname);
static void DeleteAttributeTuples(Relation rel);
static void DeleteRelationTuple(Relation rel);
static void DeleteTypeTuple(Relation rel);
......@@ -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.
*/
Form_pg_attribute
SystemAttributeDefinition(AttrNumber attno)
SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
{
if (attno >= 0 || attno < - (int) lengthof(SysAtt))
elog(ERROR, "SystemAttributeDefinition: invalid attribute number %d",
attno);
if (attno == ObjectIdAttributeNumber && !relhasoids)
elog(ERROR, "SystemAttributeDefinition: invalid attribute number %d",
attno);
return SysAtt[-attno - 1];
}
......@@ -167,9 +172,8 @@ SystemAttributeDefinition(AttrNumber attno)
/* ----------------------------------------------------------------
* heap_create - Create an uncataloged heap relation
*
* Fields relpages, reltuples, reltuples, relkeys, relhistory,
* relisindexed, and relkind of rel->rd_rel are initialized
* to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1.
* rel->rd_rel is initialized by RelationBuildLocalRelation,
* and is mostly zeroes at return.
*
* Remove the system relation specific code to elsewhere eventually.
*
......@@ -337,7 +341,7 @@ heap_storage_create(Relation rel)
* --------------------------------
*/
static void
CheckAttributeNames(TupleDesc tupdesc)
CheckAttributeNames(TupleDesc tupdesc, bool relhasoids)
{
int i;
int j;
......@@ -352,21 +356,20 @@ CheckAttributeNames(TupleDesc tupdesc)
for (i = 0; i < natts; i++)
{
for (j = 0; j < (int) lengthof(SysAtt); j++)
{
if (relhasoids || SysAtt[j]->attnum != ObjectIdAttributeNumber)
{
if (strcmp(NameStr(SysAtt[j]->attname),
NameStr(tupdesc->attrs[i]->attname)) == 0)
{
elog(ERROR, "name of column \"%s\" conflicts with an existing system column",
NameStr(SysAtt[j]->attname));
}
}
if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
{
elog(NOTICE, "Attribute '%s' has an unknown type"
"\n\tRelation created; continue",
"\n\tProceeding with relation creation anyway",
NameStr(tupdesc->attrs[i]->attname));
}
}
/*
* next check for repeated attribute names
......@@ -377,12 +380,10 @@ CheckAttributeNames(TupleDesc tupdesc)
{
if (strcmp(NameStr(tupdesc->attrs[j]->attname),
NameStr(tupdesc->attrs[i]->attname)) == 0)
{
elog(ERROR, "column name \"%s\" is duplicated",
NameStr(tupdesc->attrs[j]->attname));
}
}
}
}
/* --------------------------------
......@@ -461,7 +462,8 @@ RelnameFindRelid(const char *relname)
*/
static void
AddNewAttributeTuples(Oid new_rel_oid,
TupleDesc tupdesc)
TupleDesc tupdesc,
bool relhasoids)
{
Form_pg_attribute *dpp;
int i;
......@@ -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;
for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
{
if (relhasoids || (*dpp)->attnum != ObjectIdAttributeNumber)
{
Form_pg_attribute attStruct;
......@@ -533,6 +537,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
heap_freetuple(tup);
}
dpp++;
}
......@@ -557,8 +562,8 @@ AddNewRelationTuple(Relation pg_class_desc,
Relation new_rel_desc,
Oid new_rel_oid,
Oid new_type_oid,
int natts,
char relkind,
bool relhasoids,
char *temp_relname)
{
Form_pg_class new_rel_reltup;
......@@ -610,7 +615,7 @@ AddNewRelationTuple(Relation pg_class_desc,
new_rel_reltup->relowner = GetUserId();
new_rel_reltup->reltype = new_type_oid;
new_rel_reltup->relkind = relkind;
new_rel_reltup->relnatts = natts;
new_rel_reltup->relhasoids = relhasoids;
/* ----------------
* now form a tuple to add to pg_class
......@@ -697,6 +702,7 @@ Oid
heap_create_with_catalog(char *relname,
TupleDesc tupdesc,
char relkind,
bool relhasoids,
bool istemp,
bool allow_system_table_mods)
{
......@@ -704,18 +710,17 @@ heap_create_with_catalog(char *relname,
Relation new_rel_desc;
Oid new_rel_oid;
Oid new_type_oid;
int natts = tupdesc->natts;
char *temp_relname = NULL;
/*
* sanity checks
*/
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)",
MaxHeapAttributeNumber);
CheckAttributeNames(tupdesc);
CheckAttributeNames(tupdesc, relhasoids);
/* temp tables can mask non-temp tables */
if ((!istemp && RelnameFindRelid(relname)) ||
......@@ -763,8 +768,8 @@ heap_create_with_catalog(char *relname,
new_rel_desc,
new_rel_oid,
new_type_oid,
natts,
relkind,
relhasoids,
temp_relname);
/*
......@@ -780,16 +785,10 @@ heap_create_with_catalog(char *relname,
* now add tuples to pg_attribute for the attributes in our new
* relation.
*/
AddNewAttributeTuples(new_rel_oid, tupdesc);
AddNewAttributeTuples(new_rel_oid, tupdesc, relhasoids);
StoreConstraints(new_rel_desc);
if (istemp)
{
pfree(relname);
pfree(temp_relname);
}
/*
* We create the disk file for this relation here
*/
......@@ -799,12 +798,16 @@ heap_create_with_catalog(char *relname,
/*
* ok, the relation has been cataloged, so close our relations and
* 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(pg_class_desc, RowExclusiveLock);
if (istemp)
{
pfree(relname);
pfree(temp_relname);
}
return new_rel_oid;
}
......@@ -1120,9 +1123,6 @@ DeleteAttributeTuples(Relation rel)
0, 0);
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);
heap_freetuple(tup);
}
......@@ -1333,7 +1333,7 @@ heap_drop_with_catalog(const char *relname,
/*
* delete comments, statistics, and constraints
*/
DeleteComments(RelationGetRelid(rel));
DeleteComments(rid, RelOid_pg_class);
RemoveStatistics(rel);
......
......@@ -8,7 +8,7 @@
*
*
* 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
......@@ -229,7 +229,8 @@ ConstructTupleDescriptor(Relation heapRelation,
/*
* here we are indexing on a system attribute (-1...-n)
*/
from = SystemAttributeDefinition(atnum);
from = SystemAttributeDefinition(atnum,
heapRelation->rd_rel->relhasoids);
}
else
{
......@@ -355,6 +356,7 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid)
indexRelation->rd_rel->relisshared =
IsSharedSystemRelationName(RelationGetPhysicalRelationName(indexRelation));
indexRelation->rd_rel->relkind = RELKIND_INDEX;
indexRelation->rd_rel->relhasoids = false;
}
/* ----------------------------------------------------------------
......@@ -659,9 +661,11 @@ InitIndexStrategy(int numatts,
/* ----------------------------------------------------------------
* index_create
*
* Returns OID of the created index.
* ----------------------------------------------------------------
*/
void
Oid
index_create(char *heapRelationName,
char *indexRelationName,
IndexInfo *indexInfo,
......@@ -803,6 +807,8 @@ index_create(char *heapRelationName,
}
else
index_build(heapRelation, indexRelation, indexInfo);
return indexoid;
}
/* ----------------------------------------------------------------
......@@ -852,7 +858,7 @@ index_drop(Oid indexId)
/*
* fix DESCRIPTION relation
*/
DeleteComments(indexId);
DeleteComments(indexId, RelOid_pg_class);
/*
* fix RELATION relation
......@@ -877,8 +883,11 @@ index_drop(Oid indexId)
* must send out a shared-cache-inval notice on the owning relation to
* ensure other backends update their relcache lists of indexes. So,
* 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);
......@@ -1199,6 +1208,12 @@ IndexesAreActive(Oid relid, bool confirmCommitted)
/* ----------------
* 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
* message is sent out to all backends --- including me --- causing relcache
* entries to be flushed or updated with the new hasindex data.
......@@ -1208,10 +1223,11 @@ IndexesAreActive(Oid relid, bool confirmCommitted)
* ----------------
*/
void
setRelhasindex(Oid relid, bool hasindex)
setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
{
Relation pg_class;
HeapTuple tuple;
Form_pg_class classtuple;
HeapScanDesc pg_class_scan = NULL;
/*
......@@ -1219,7 +1235,8 @@ setRelhasindex(Oid relid, bool hasindex)
*/
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,
ObjectIdGetDatum(relid),
......@@ -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)
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)
LockBuffer(pg_class_scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
......@@ -1945,7 +1972,7 @@ activate_indexes_of_a_table(Oid relid, bool activate)
if (IndexesAreActive(relid, true))
{
if (!activate)
setRelhasindex(relid, false);
setRelhasindex(relid, false, false, InvalidOid);
else
return false;
}
......@@ -2081,7 +2108,7 @@ reindex_relation(Oid relid, bool force)
* For pg_class, relhasindex should be set to true here in
* place.
*/
setRelhasindex(relid, true);
setRelhasindex(relid, true, false, InvalidOid);
CommandCounterIncrement();
/*
......@@ -2089,7 +2116,7 @@ reindex_relation(Oid relid, bool force)
* keep consistency with WAL.
*/
}
setRelhasindex(relid, true);
setRelhasindex(relid, true, false, InvalidOid);
}
}
SetReindexProcessing(old);
......
......@@ -9,7 +9,7 @@
*
*
* 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 @@
*/
char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] =
{AggregateNameTypeIndex};
{AggregateNameTypeIndex, AggregateOidIndex};
char *Name_pg_am_indices[Num_pg_am_indices] =
{AmNameIndex, AmOidIndex};
char *Name_pg_amop_indices[Num_pg_amop_indices] =
......
......@@ -15,7 +15,7 @@
*
*
* 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)
tupdesc = CreateTupleDescCopyConstr(OldHeapDesc);
OIDNewHeap = heap_create_with_catalog(NewName, tupdesc,
RELKIND_RELATION, istemp,
OldHeap->rd_rel->relkind,
OldHeap->rd_rel->relhasoids,
istemp,
allowSystemTableMods);
/*
......@@ -227,7 +229,8 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName)
Old_pg_index_Form->indisprimary,
allowSystemTableMods);
setRelhasindex(OIDNewHeap, true);
setRelhasindex(OIDNewHeap, true,
Old_pg_index_Form->indisprimary, InvalidOid);
ReleaseSysCache(Old_pg_index_Tuple);
ReleaseSysCache(Old_pg_index_relation_Tuple);
......
......@@ -8,7 +8,7 @@
*
*
* 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
* The PerformAddAttribute() code, like most of the relation
......@@ -102,7 +102,7 @@ PerformPortalFetch(char *name,
QueryDesc *queryDesc;
EState *estate;
MemoryContext oldcontext;
bool faked_desc = false;
bool temp_desc = false;
/*
* sanity checks
......@@ -130,24 +130,33 @@ PerformPortalFetch(char *name,
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
* appropriate dummy destination.
* EXCEPTION: if the query's original dest is RemoteInternal (ie, it's
* 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);
estate = PortalGetState(portal);
if (dest != queryDesc->dest) /* MOVE */
if (dest != queryDesc->dest &&
!(queryDesc->dest == RemoteInternal && dest == Remote))
{
QueryDesc *qdesc = (QueryDesc *) palloc(sizeof(QueryDesc));
memcpy(qdesc, queryDesc, sizeof(QueryDesc));
qdesc->dest = dest;
queryDesc = qdesc;
faked_desc = true;
temp_desc = true;
}
/*
* tell the destination to prepare to receive some tuples.
*/
BeginCommand(name,
queryDesc->operation,
PortalGetTupleDesc(portal),
......@@ -156,7 +165,7 @@ PerformPortalFetch(char *name,
false, /* this is a portal fetch, not a "retrieve
* portal" */
tag,
dest);
queryDesc->dest);
/*
* Determine which direction to go in, and check to see if we're
......@@ -205,7 +214,7 @@ PerformPortalFetch(char *name,
/*
* Clean up and switch back to old context.
*/
if (faked_desc) /* MOVE */
if (temp_desc)
pfree(queryDesc);
MemoryContextSwitchTo(oldcontext);
......@@ -1004,8 +1013,7 @@ AlterTableDropColumn(const char *relationName,
#ifdef _DROP_COLUMN_HACK__
Relation rel,
attrdesc;
Oid myrelid,
attoid;
Oid myrelid;
HeapTuple reltup;
HeapTupleData classtuple;
Buffer buffer;
......@@ -1094,7 +1102,6 @@ AlterTableDropColumn(const char *relationName,
if (attnum <= 0)
elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped",
colName);
attoid = tup->t_data->t_oid;
/*
* Check constraints/indices etc here
......@@ -1124,8 +1131,9 @@ AlterTableDropColumn(const char *relationName,
heap_close(attrdesc, NoLock);
heap_freetuple(tup);
/* delete comments */
DeleteComments(attoid);
/* delete comment for this attribute only */
CreateComments(RelationGetRelid(rel), RelOid_pg_class,
(int32) attnum, NULL);
/* delete attrdef */
drop_default(myrelid, attnum);
......@@ -1750,9 +1758,8 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
Oid toast_idxid;
char toast_relname[NAMEDATALEN + 1];
char toast_idxname[NAMEDATALEN + 1];
Relation toast_idxrel;
IndexInfo *indexInfo;
Oid classObjectId[1];
Oid classObjectId[2];
/*
* permissions checking. XXX exactly what is appropriate here?
......@@ -1870,50 +1877,49 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
* so there's no need to handle the toast rel as temp.
*/
toast_relid = heap_create_with_catalog(toast_relname, tupdesc,
RELKIND_TOASTVALUE,
RELKIND_TOASTVALUE, false,
false, true);
/* make the toast relation visible, else index creation will fail */
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->ii_NumIndexAttrs = 1;
indexInfo->ii_NumKeyAttrs = 1;
indexInfo->ii_NumIndexAttrs = 2;
indexInfo->ii_NumKeyAttrs = 2;
indexInfo->ii_KeyAttrNumbers[0] = 1;
indexInfo->ii_KeyAttrNumbers[1] = 2;
indexInfo->ii_Predicate = NIL;
indexInfo->ii_FuncOid = InvalidOid;
indexInfo->ii_Unique = false;
indexInfo->ii_Unique = true;
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,
false, false, true);
false, true, true);
/*
* 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);
/*
* 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);
setRelhasindex(toast_relid, true, true, toast_idxid);
/*
* 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))->reltoastidxid = toast_idxid;
simple_heap_update(class_rel, &reltup->t_self, reltup);
/*
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
*
*
* 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)
/*
* 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
DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
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;
Relation rel;
const AclMode required_access = from ? ACL_INSERT : ACL_SELECT;
const AclMode required_access = (from ? ACL_INSERT : ACL_SELECT);
int result;
/*
......@@ -305,10 +307,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
if (from)
{ /* copy from file to database */
if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
elog(ERROR, "You cannot change sequence relation %s", relname);
if (rel->rd_rel->relkind != RELKIND_RELATION)
{
if (rel->rd_rel->relkind == RELKIND_VIEW)
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 (IsUnderPostmaster)
......@@ -332,8 +339,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
}
else
{ /* copy from database to file */
if (rel->rd_rel->relkind != RELKIND_RELATION)
{
if (rel->rd_rel->relkind == RELKIND_VIEW)
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 (IsUnderPostmaster)
......@@ -410,6 +424,10 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp,
int16 fld_size;
char *string;
if (oids && !rel->rd_rel->relhasoids)
elog(ERROR, "COPY: table %s does not have OIDs",
RelationGetRelationName(rel));
tupDesc = rel->rd_att;
attr_count = rel->rd_att->natts;
attr = rel->rd_att->attrs;
......@@ -706,6 +724,10 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
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));
nulls = (char *) palloc(attr_count * sizeof(char));
......
......@@ -8,7 +8,7 @@
*
*
* 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 @@
*/
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 void StoreCatalogInheritance(Oid relationId, List *supers);
static int findAttrByName(const char *attributeName, List *schema);
......@@ -57,6 +57,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
TupleDesc descriptor;
List *inheritOids;
List *old_constraints;
bool parentHasOids;
List *rawDefaults;
List *listptr;
int i;
......@@ -73,7 +74,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
* including inherited attributes.
*/
schema = MergeAttributes(schema, stmt->inhRelnames, stmt->istemp,
&inheritOids, &old_constraints);
&inheritOids, &old_constraints, &parentHasOids);
numberOfAttributes = length(schema);
if (numberOfAttributes <= 0)
......@@ -135,7 +136,9 @@ DefineRelation(CreateStmt *stmt, char relkind)
}
relationId = heap_create_with_catalog(relname, descriptor,
relkind, stmt->istemp,
relkind,
stmt->hasoids || parentHasOids,
stmt->istemp,
allowSystemTableMods);
StoreCatalogInheritance(relationId, inheritOids);
......@@ -248,6 +251,7 @@ TruncateRelation(char *name)
* 'supOids' receives an integer list of the OIDs of the parent relations.
* 'supconstr' receives a list of constraints belonging to the parents,
* 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:
* Completed schema list.
......@@ -293,12 +297,13 @@ TruncateRelation(char *name)
*/
static List *
MergeAttributes(List *schema, List *supers, bool istemp,
List **supOids, List **supconstr)
List **supOids, List **supconstr, bool *supHasOids)
{
List *entry;
List *inhSchema = NIL;
List *parentOids = NIL;
List *constraints = NIL;
bool parentHasOids = false;
bool have_bogus_defaults = false;
char *bogus_marker = "Bogus!"; /* marks conflicting defaults */
int child_attno;
......@@ -341,7 +346,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
/*
* 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;
foreach(entry, supers)
......@@ -371,6 +377,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
parentOids = lappendi(parentOids, relation->rd_id);
setRelhassubclassInRelation(relation->rd_id, true);
parentHasOids |= relation->rd_rel->relhasoids;
tupleDesc = RelationGetDescr(relation);
constr = tupleDesc->constr;
......@@ -598,6 +606,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
*supOids = parentOids;
*supconstr = constraints;
*supHasOids = parentHasOids;
return schema;
}
......
......@@ -9,7 +9,7 @@
*
*
* 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)
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
* that any new backend scanning pg_database will see the tuple dead.
*/
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.
* This is important to ensure that no remaining backend tries to
......
......@@ -8,7 +8,7 @@
*
*
* 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,
* backends to flush their relcache entries and in particular their
* cached lists of the indexes for this relation.
*/
setRelhasindex(relationId, true);
setRelhasindex(relationId, true, primary, InvalidOid);
}
......
......@@ -8,7 +8,7 @@
*
*
* 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 */
elog(ERROR, "RemoveOperator: operator '%s': permission denied",
operatorName);
/*** Delete any comments associated with this operator ***/
DeleteComments(tup->t_data->t_oid);
/* Delete any comments associated with this operator */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
simple_heap_delete(relation, &tup->t_self);
......@@ -146,11 +145,8 @@ SingleOpOperatorRemove(Oid typeOid)
scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
{
/*** This is apparently a routine not in use, but remove ***/
/*** any comments anyways ***/
DeleteComments(tup->t_data->t_oid);
/* Delete any comments associated with this operator */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(rel));
simple_heap_delete(rel, &tup->t_self);
}
......@@ -242,7 +238,6 @@ RemoveType(char *typeName) /* type name to be removed */
{
Relation relation;
HeapTuple tup;
Oid typeOid;
char *shadow_type;
if (!pg_ownercheck(GetUserId(), typeName, TYPENAME))
......@@ -257,11 +252,8 @@ RemoveType(char *typeName) /* type name to be removed */
if (!HeapTupleIsValid(tup))
elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
typeOid = tup->t_data->t_oid;
/*** Delete any comments associated with this type ***/
DeleteComments(typeOid);
/* Delete any comments associated with this type */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
simple_heap_delete(relation, &tup->t_self);
......@@ -347,9 +339,8 @@ RemoveFunction(char *functionName, /* function name to be removed */
elog(NOTICE, "Removing built-in function \"%s\"", functionName);
}
/*** Delete any comments associated with this function ***/
DeleteComments(tup->t_data->t_oid);
/* Delete any comments associated with this function */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
simple_heap_delete(relation, &tup->t_self);
......@@ -421,9 +412,8 @@ RemoveAggregate(char *aggName, char *aggType)
}
}
/*** Remove any comments related to this aggregate ***/
DeleteComments(tup->t_data->t_oid);
/* Remove any comments related to this aggregate */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
simple_heap_delete(relation, &tup->t_self);
......
......@@ -8,7 +8,7 @@
*
*
* 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)
}
stmt->relname = seq->seqname;
stmt->istemp = seq->istemp;
stmt->inhRelnames = NIL;
stmt->constraints = NIL;
stmt->istemp = seq->istemp;
stmt->hasoids = false;
DefineRelation(stmt, RELKIND_SEQUENCE);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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)
if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
{
/*** Delete any comments associated with this trigger ***/
DeleteComments(tuple->t_data->t_oid);
/* Delete any comments associated with this trigger */
DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel));
simple_heap_delete(tgrel, &tuple->t_self);
tgfound++;
......@@ -407,10 +405,8 @@ RelationRemoveTriggers(Relation rel)
while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0)))
{
/*** Delete any comments associated with this trigger ***/
DeleteComments(tup->t_data->t_oid);
/* Delete any comments associated with this trigger */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(tgrel));
simple_heap_delete(tgrel, &tup->t_self);
......
......@@ -13,7 +13,7 @@
*
*
* 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,
pgcform->relpages = (int32) num_pages;
pgcform->reltuples = num_tuples;
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 */
RelationInvalidateHeapTuple(rd, &rtup);
......@@ -904,7 +910,8 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
/*
* 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.",
relname, blkno, offnum, (int) tupgone);
......
......@@ -31,7 +31,7 @@
*
*
* 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,
/*
* 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.",
relname, blkno, offnum, (int) tupgone);
......
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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)
* nil...
*/
createStmt->relname = relname;
createStmt->istemp = false;
createStmt->tableElts = attrList;
createStmt->inhRelnames = NIL;
createStmt->constraints = NIL;
createStmt->istemp = false;
createStmt->hasoids = false;
/*
* finally create the relation...
......
......@@ -27,7 +27,7 @@
*
*
* 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)
intoRelationId =
heap_create_with_catalog(intoName,
tupdesc,
RELKIND_RELATION,
RELKIND_RELATION, true,
parseTree->isTemp,
allowSystemTableMods);
......
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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)
{
CreateStmt *newnode = makeNode(CreateStmt);
newnode->istemp = from->istemp;
newnode->relname = pstrdup(from->relname);
Node_Copy(from, newnode, tableElts);
Node_Copy(from, newnode, inhRelnames);
Node_Copy(from, newnode, constraints);
newnode->istemp = from->istemp;
newnode->hasoids = from->hasoids;
return newnode;
}
......
......@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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)
static bool
_equalCreateStmt(CreateStmt *a, CreateStmt *b)
{
if (a->istemp != b->istemp)
return false;
if (!equalstr(a->relname, b->relname))
return false;
if (!equal(a->tableElts, b->tableElts))
......@@ -829,6 +827,10 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
return false;
if (!equal(a->constraints, b->constraints))
return false;
if (a->istemp != b->istemp)
return false;
if (a->hasoids != b->hasoids)
return false;
return true;
}
......
......@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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
* Every (plan) node in POSTGRES has an associated "out" routine which
......@@ -108,9 +108,6 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
appendStringInfo(str, " CREATE :relname ");
_outToken(str, node->relname);
appendStringInfo(str, " :istemp %s ",
booltostr(node->istemp));
appendStringInfo(str, " :columns ");
_outNode(str, node->tableElts);
......@@ -119,6 +116,10 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
appendStringInfo(str, " :constraints ");
_outNode(str, node->constraints);
appendStringInfo(str, " :istemp %s :hasoids %s ",
booltostr(node->istemp),
booltostr(node->hasoids));
}
static void
......
......@@ -11,7 +11,7 @@
*
*
* 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
* AUTHOR DATE MAJOR EVENT
......@@ -198,7 +198,7 @@ static void doNegateFloat(Value *v);
%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 <boolean> opt_all
......@@ -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);
n->istemp = $2;
n->relname = $4;
n->tableElts = $6;
n->inhRelnames = $8;
n->constraints = NIL;
n->istemp = $2;
n->hasoids = $9;
$$ = (Node *)n;
}
;
......@@ -1541,6 +1542,12 @@ OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
| /*EMPTY*/ { $$ = NIL; }
;
OptWithOids: WITH OIDS { $$ = TRUE; }
| WITHOUT OIDS { $$ = FALSE; }
| /*EMPTY*/ { $$ = TRUE; }
;
/*
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for
* SELECT ... INTO.
......
......@@ -8,7 +8,7 @@
*
*
* 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 @@
#include "rewrite/rewriteManip.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
static Node *scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
......@@ -38,6 +39,7 @@ static Node *scanJoinForColumn(JoinExpr *join, char *colname,
int sublevels_up);
static bool isForUpdate(ParseState *pstate, char *relname);
static List *expandNamesVars(ParseState *pstate, List *names, List *vars);
static int specialAttNum(char *a);
static void warnAutoRange(ParseState *pstate, char *refname);
......@@ -318,13 +320,21 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
*/
if (rte->relid != InvalidOid)
{
/* quick check to see if name could be a system column */
attnum = specialAttNum(colname);
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);
rte->checkForRead = true;
}
}
}
return result;
}
......@@ -968,7 +978,10 @@ attnameAttNum(Relation rd, char *a)
return i + 1;
if ((i = specialAttNum(a)) != InvalidAttrNumber)
{
if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
return i;
}
/* on failure */
elog(ERROR, "Relation '%s' does not have attribute '%s'",
......@@ -977,10 +990,15 @@ attnameAttNum(Relation rd, char *a)
}
/* specialAttNum()
*
* Check attribute name to see if it is "special", e.g. "oid".
* - 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)
{
int i;
......@@ -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 */
/*
* This should only be used if the relation is already
* heap_open()'ed. Use the cache version get_atttype()
* 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
attnumTypeId(Relation rd, int attid)
......
......@@ -8,7 +8,7 @@
*
*
* 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)
/*
* Delete any comments associated with this rule
*/
DeleteComments(ruleId);
DeleteComments(ruleId, RelationGetRelid(RewriteRelation));
/*
* Now delete the pg_rewrite tuple for the rule
......@@ -175,10 +175,8 @@ RelationRemoveRules(Oid relid)
while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
{
/*** Delete any comments associated with this relation ***/
DeleteComments(tuple->t_data->t_oid);
/* Delete any comments associated with this rule */
DeleteComments(tuple->t_data->t_oid, RelationGetRelid(RewriteRelation));
simple_heap_delete(RewriteRelation, &tuple->t_self);
}
......
......@@ -8,7 +8,7 @@
*
*
* 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,
relation->rd_rel->relpages = 1;
relation->rd_rel->reltuples = 1;
relation->rd_rel->relkind = RELKIND_RELATION;
relation->rd_rel->relhasoids = true;
relation->rd_rel->relnatts = (int16) natts;
/*
......@@ -1988,6 +1989,7 @@ RelationBuildLocalRelation(const char *relname,
strcpy(RelationGetPhysicalRelationName(rel), relname);
rel->rd_rel->relkind = RELKIND_UNCATALOGED;
rel->rd_rel->relhasoids = true;
rel->rd_rel->relnatts = natts;
rel->rd_rel->reltype = InvalidOid;
if (tupDesc->constr)
......
......@@ -8,7 +8,7 @@
*
*
* 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
* These routines allow the parser/planner/executor to perform
......@@ -485,6 +485,28 @@ SearchSysCacheCopy(int cacheId,
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
*
......
......@@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# 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 \
# To break an SQL command across lines in this script, backslash-escape all
# 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
-- Create a trigger so that direct updates to pg_shadow will be written
......@@ -682,7 +687,7 @@ CREATE VIEW pg_statio_all_tables AS \
FROM pg_class C 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 X ON C.reltoastidxid = X.oid \
pg_class X ON T.reltoastidxid = X.oid \
WHERE C.relkind = 'r' \
GROUP BY C.oid, C.relname, T.oid, X.oid;
......@@ -793,23 +798,24 @@ fi
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 <<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
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."
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
......@@ -823,10 +829,17 @@ echo "Copying template1 to template0."
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
CREATE DATABASE template0;
UPDATE pg_database SET \
datistemplate = 't', \
datallowconn = 'f' \
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;
EOF
if [ "$?" -ne 0 ]; then
......
This diff is collapsed.
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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
*
......@@ -63,7 +63,7 @@ typedef struct _funcInfo
char *oid;
char *proname;
char *proowner;
int lang;
Oid lang;
int nargs;
char *argtypes[FUNC_MAX_ARGS];
char *prorettype;
......@@ -97,6 +97,7 @@ typedef struct _tableInfo
* created after the base table was created.
*/
bool sequence;
bool hasoids; /* does it have OIDs? */
int numatts; /* number of attributes */
int *inhAttrs; /* an array of flags, one for each
* attribute if the value is 1, then this
......@@ -104,7 +105,6 @@ typedef struct _tableInfo
int *inhAttrDef; /* Flags indicating if attrdef is inherited */
int *inhNotNull; /* Flags indicating if NOT NULL in inherited */
char **attnames; /* the attribute names */
char **attoids; /* oids of the various attributes */
char **atttypedefns; /* formatted column type definitions */
char **typnames; /* fill out attributes */
bool *notnull; /* Not null constraints of an attribute */
......
......@@ -3,7 +3,7 @@
*
* 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 "describe.h"
......@@ -51,7 +51,7 @@ describeAggregates(const char *name)
" WHEN 0 THEN CAST('%s' AS text)\n"
" ELSE format_type(a.aggbasetype, NULL)\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",
_("Name"), _("(all types)"),
_("Data type"), _("Description") );
......@@ -105,7 +105,7 @@ describeFunctions(const char *name, bool verbose)
",\n u.usename as \"%s\",\n"
" l.lanname as \"%s\",\n"
" p.prosrc as \"%s\",\n"
" obj_description(p.oid) as \"%s\"",
" obj_description(p.oid, 'pg_proc') as \"%s\"",
_("Owner"), _("Language"),
_("Source code"), _("Description") );
......@@ -165,7 +165,7 @@ describeTypes(const char *name, bool verbose)
" END AS \"%s\",\n",
_("Internal name"), _("Size") );
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") );
/*
......@@ -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='r' THEN NULL ELSE format_type(o.oprright, NULL) END 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"
"WHERE RegprocToOid(o.oprcode) = p.oid\n",
_("Name"), _("Left arg type"), _("Right arg type"),
......@@ -265,7 +265,7 @@ listAllDbs(bool desc)
#endif
if (desc)
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"));
strcat(buf,
"\nFROM pg_database d LEFT JOIN pg_user u ON d.datdba = u.usesysid\n"
......@@ -348,28 +348,34 @@ objectDescription(const char *object)
"FROM (\n"
/* 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"
/* Function descriptions (except in/outs for datatypes) */
"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"
" WHERE p.pronargs = 0 or oidvectortypes(p.proargtypes) <> ''\n"
/* Operator descriptions (must get comment via associated function) */
"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"
/* Type description */
"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"
/* Relation (tables, views, indexes, sequences) descriptions */
"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"
" 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"
......@@ -377,18 +383,20 @@ objectDescription(const char *object)
/* Rule description (ignore rules for views) */
"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"
" WHERE r.rulename !~ '^_RET'\n"
/* Trigger description */
"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"
") AS tt,\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"),
_("aggregate"), _("function"), _("operator"),
......@@ -528,7 +536,7 @@ describeTableDetails(const char *name, bool desc)
/* Get column info */
strcpy(buf, "SELECT a.attname, format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, a.attnum");
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"
"WHERE c.relname = '");
strncat(buf, name, NAMEDATALEN);
......@@ -1025,7 +1033,7 @@ listTables(const char *infotype, const char *name, bool desc)
if (desc)
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"));
strcat(buf,
"\nFROM pg_class c LEFT JOIN pg_user u ON c.relowner = u.usesysid\n"
......
......@@ -3,7 +3,7 @@
*
* 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 "large_obj.h"
......@@ -149,7 +149,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
{
PGresult *res;
Oid loid;
char buf[1024];
char oidbuf[32];
unsigned int i;
bool own_transaction = true;
const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
......@@ -189,23 +189,46 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
/* insert description if given */
if (comment_arg)
{
sprintf(buf, "INSERT INTO pg_description VALUES (%u, '", loid);
for (i = 0; i < strlen(comment_arg); i++)
if (comment_arg[i] == '\'')
strcat(buf, "\\'");
else
strncat(buf, &comment_arg[i], 1);
strcat(buf, "')");
char *cmdbuf;
char *bufptr;
int slen = strlen(comment_arg);
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)
{
res = PQexec(pset.db, "ROLLBACK");
PQclear(res);
}
free(cmdbuf);
return false;
}
PQclear(res);
free(cmdbuf);
}
if (own_transaction)
......@@ -221,9 +244,9 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
}
fprintf(pset.queryFout, "lo_import %d\n", loid);
sprintf(buf, "%u", (unsigned int) loid);
SetVariable(pset.vars, "LASTOID", buf);
fprintf(pset.queryFout, "lo_import %u\n", loid);
sprintf(oidbuf, "%u", loid);
SetVariable(pset.vars, "LASTOID", oidbuf);
return true;
}
......@@ -278,7 +301,9 @@ do_lo_unlink(const char *loid_arg)
}
/* 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 (own_transaction)
......@@ -322,7 +347,7 @@ do_lo_list(void)
printQueryOpt myopt = pset.popt;
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"
"ORDER BY \"ID\"",
gettext("Description"));
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 @@
typedef unsigned char XidStatus; /* (2 bits) */
/* ----------
* We reserve the first 16384 object ids for manual assignment.
* oid's less than this appear in the .bki files. the choice of
* 16384 is completely arbitrary.
* Object ID (OID) zero is InvalidOid.
*
* 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
/*
......@@ -111,7 +127,7 @@ extern void TransBlockNumberSetXidStatus(Relation relation,
/* in transam/varsup.c */
extern void GetNewTransactionId(TransactionId *xid);
extern void ReadNewTransactionId(TransactionId *xid);
extern void GetNewObjectId(Oid *oid_return);
extern Oid GetNewObjectId(void);
extern void CheckMaxObjectId(Oid assigned_oid);
/* ----------------
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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);
extern char *LexIDStr(int ident_num);
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 char *MapArrayTypeName(char *s);
extern char *CleanUpStr(char *s);
......
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200107151
#define CATALOG_VERSION_NO 200108101
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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,
extern void heap_storage_create(Relation rel);
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);
extern void heap_drop_with_catalog(const char *relname,
......@@ -48,6 +48,7 @@ extern void AddRelationRawConstraints(Relation rel,
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 */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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,
Relation indexRelation,
Oid accessMethodObjectId);
extern void index_create(char *heapRelationName,
extern Oid index_create(char *heapRelationName,
char *indexRelationName,
IndexInfo *indexInfo,
Oid accessMethodObjectId,
......@@ -56,7 +56,8 @@ extern void FormIndexDatum(IndexInfo *indexInfo,
extern void UpdateStats(Oid relid, double reltuples);
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);
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 @@
/*
* 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_amop_indices 2
#define Num_pg_amproc_indices 1
......@@ -51,6 +51,7 @@
#define AccessMethodStrategyIndex "pg_amop_strategy_index"
#define AccessProcedureIndex "pg_amproc_am_opcl_procnum_index"
#define AggregateNameTypeIndex "pg_aggregate_name_type_index"
#define AggregateOidIndex "pg_aggregate_oid_index"
#define AmNameIndex "pg_am_name_index"
#define AmOidIndex "pg_am_oid_index"
#define AttrDefaultIndex "pg_attrdef_adrelid_adnum_index"
......@@ -60,7 +61,7 @@
#define ClassOidIndex "pg_class_oid_index"
#define DatabaseNameIndex "pg_database_datname_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 GroupSysidIndex "pg_group_sysid_index"
#define IndexIndrelidIndex "pg_index_indrelid_index"
......@@ -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_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_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));
......@@ -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_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_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_sysid_index on pg_group using btree(grosysid int4_ops));
/* This following index is not used for a cache and is not unique */
......
This diff is collapsed.
......@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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
* the genbki.sh script reads this file and generates .bki
......@@ -33,7 +33,7 @@
* typedef struct FormData_pg_amproc
* ----------------
*/
CATALOG(pg_amproc)
CATALOG(pg_amproc) BKI_WITHOUT_OIDS
{
Oid amid; /* the access method this proc is for */
Oid amopclaid; /* the opclass this proc is for */
......@@ -64,65 +64,65 @@ typedef FormData_pg_amproc *Form_pg_amproc;
*/
/* rtree */
DATA(insert OID = 0 (402 422 193 1));
DATA(insert OID = 0 (402 422 194 2));
DATA(insert OID = 0 (402 422 195 3));
DATA(insert OID = 0 (402 433 193 1));
DATA(insert OID = 0 (402 433 194 2));
DATA(insert OID = 0 (402 433 196 3));
DATA(insert OID = 0 (402 434 197 1));
DATA(insert OID = 0 (402 434 198 2));
DATA(insert OID = 0 (402 434 199 3));
DATA(insert (402 422 193 1));
DATA(insert (402 422 194 2));
DATA(insert (402 422 195 3));
DATA(insert (402 433 193 1));
DATA(insert (402 433 194 2));
DATA(insert (402 433 196 3));
DATA(insert (402 434 197 1));
DATA(insert (402 434 198 2));
DATA(insert (402 434 199 3));
/* btree */
DATA(insert OID = 0 (403 421 350 1));
DATA(insert OID = 0 (403 423 355 1));
DATA(insert OID = 0 (403 426 351 1));
DATA(insert OID = 0 (403 427 356 1));
DATA(insert OID = 0 (403 428 354 1));
DATA(insert OID = 0 (403 429 358 1));
DATA(insert OID = 0 (403 431 360 1));
DATA(insert OID = 0 (403 432 357 1));
DATA(insert OID = 0 (403 435 404 1));
DATA(insert OID = 0 (403 754 842 1));
DATA(insert OID = 0 (403 1076 1078 1));
DATA(insert OID = 0 (403 1077 1079 1));
DATA(insert OID = 0 (403 1114 1092 1));
DATA(insert OID = 0 (403 1115 1107 1));
DATA(insert OID = 0 (403 1181 359 1));
DATA(insert OID = 0 (403 1312 1314 1));
DATA(insert OID = 0 (403 1313 1315 1));
DATA(insert OID = 0 (403 810 836 1));
DATA(insert OID = 0 (403 935 926 1));
DATA(insert OID = 0 (403 652 926 1));
DATA(insert OID = 0 (403 1768 1769 1));
DATA(insert OID = 0 (403 1690 1693 1));
DATA(insert OID = 0 (403 1399 1358 1));
DATA(insert OID = 0 (403 424 1596 1));
DATA(insert OID = 0 (403 425 1672 1));
DATA(insert (403 421 350 1));
DATA(insert (403 423 355 1));
DATA(insert (403 426 351 1));
DATA(insert (403 427 356 1));
DATA(insert (403 428 354 1));
DATA(insert (403 429 358 1));
DATA(insert (403 431 360 1));
DATA(insert (403 432 357 1));
DATA(insert (403 435 404 1));
DATA(insert (403 754 842 1));
DATA(insert (403 1076 1078 1));
DATA(insert (403 1077 1079 1));
DATA(insert (403 1114 1092 1));
DATA(insert (403 1115 1107 1));
DATA(insert (403 1181 359 1));
DATA(insert (403 1312 1314 1));
DATA(insert (403 1313 1315 1));
DATA(insert (403 810 836 1));
DATA(insert (403 935 926 1));
DATA(insert (403 652 926 1));
DATA(insert (403 1768 1769 1));
DATA(insert (403 1690 1693 1));
DATA(insert (403 1399 1358 1));
DATA(insert (403 424 1596 1));
DATA(insert (403 425 1672 1));
/* hash */
DATA(insert OID = 0 (405 421 449 1));
DATA(insert OID = 0 (405 423 452 1));
DATA(insert OID = 0 (405 426 450 1));
DATA(insert OID = 0 (405 427 453 1));
DATA(insert OID = 0 (405 428 451 1));
DATA(insert OID = 0 (405 429 454 1));
DATA(insert OID = 0 (405 431 456 1));
DATA(insert OID = 0 (405 435 457 1));
DATA(insert OID = 0 (405 652 456 1));
DATA(insert OID = 0 (405 754 949 1));
DATA(insert OID = 0 (405 810 399 1));
DATA(insert OID = 0 (405 935 456 1));
DATA(insert OID = 0 (405 1076 1080 1));
DATA(insert OID = 0 (405 1077 456 1));
DATA(insert OID = 0 (405 1114 450 1));
DATA(insert OID = 0 (405 1115 452 1));
DATA(insert OID = 0 (405 1181 455 1));
DATA(insert OID = 0 (405 1312 452 1));
DATA(insert OID = 0 (405 1313 1697 1));
DATA(insert OID = 0 (405 1399 1696 1));
DATA(insert (405 421 449 1));
DATA(insert (405 423 452 1));
DATA(insert (405 426 450 1));
DATA(insert (405 427 453 1));
DATA(insert (405 428 451 1));
DATA(insert (405 429 454 1));
DATA(insert (405 431 456 1));
DATA(insert (405 435 457 1));
DATA(insert (405 652 456 1));
DATA(insert (405 754 949 1));
DATA(insert (405 810 399 1));
DATA(insert (405 935 456 1));
DATA(insert (405 1076 1080 1));
DATA(insert (405 1077 456 1));
DATA(insert (405 1114 450 1));
DATA(insert (405 1115 452 1));
DATA(insert (405 1181 455 1));
DATA(insert (405 1312 452 1));
DATA(insert (405 1313 1697 1));
DATA(insert (405 1399 1696 1));
#endif /* PG_AMPROC_H */
......@@ -27,7 +27,7 @@
* typedef struct FormData_pg_attrdef
* ----------------
*/
CATALOG(pg_attrdef)
CATALOG(pg_attrdef) BKI_WITHOUT_OIDS
{
Oid adrelid;
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