Commit 7c6df91d authored by Tom Lane's avatar Tom Lane

Second phase of committing Rod Taylor's pg_depend/pg_constraint patch.

pg_relcheck is gone; CHECK, UNIQUE, PRIMARY KEY, and FOREIGN KEY
constraints all have real live entries in pg_constraint.  pg_depend
exists, and RESTRICT/CASCADE options work on most kinds of DROP;
however, pg_depend is not yet very well populated with dependencies.
(Most of the ones that are present at this point just replace formerly
hardwired associations, such as the implicit drop of a relation's pg_type
entry when the relation is dropped.)  Need to add more logic to create
dependency entries, improve pg_dump to dump constraints in place of
indexes and triggers, and add some regression tests.
parent 791a40f9
This diff is collapsed.
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.45 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.46 2002/07/12 18:43:12 tgl Exp $
PostgreSQL documentation
-->
......@@ -39,7 +39,7 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
ADD <replaceable class="PARAMETER">table_constraint_definition</replaceable>
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable>
DROP CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> { RESTRICT | CASCADE }
DROP CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
</synopsis>
......@@ -315,26 +315,6 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
form after you've entered non-null values for the column in all rows.
</para>
<para>
In DROP CONSTRAINT, the RESTRICT keyword is required, although
dependencies are not yet checked. The CASCADE option is unsupported.
Currently DROP CONSTRAINT only handles CHECK constraints.
To remove a PRIMARY or UNIQUE constraint, drop the
relevant index using the <xref linkend="SQL-DROPINDEX" endterm="sql-dropindex-title"> command.
To remove FOREIGN KEY constraints you need to recreate
and reload the table, using other parameters to the
<xref linkend="SQL-CREATETABLE" endterm="sql-createtable-title"> command.
</para>
<para>
For example, to drop all constraints on a table <literal>distributors</literal>:
<programlisting>
CREATE TABLE temp AS SELECT * FROM distributors;
DROP TABLE distributors;
CREATE TABLE distributors AS SELECT * FROM temp;
DROP TABLE temp;
</programlisting>
</para>
<para>
Changing any part of the schema of a system
catalog is not permitted.
......@@ -395,7 +375,7 @@ ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
<para>
To remove a check constraint from a table and all its children:
<programlisting>
ALTER TABLE distributors DROP CONSTRAINT zipchk RESTRICT;
ALTER TABLE distributors DROP CONSTRAINT zipchk;
</programlisting>
</para>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.19 2002/05/13 17:45:30 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.20 2002/07/12 18:43:12 tgl Exp $
PostgreSQL documentation
-->
......@@ -26,6 +26,7 @@ COMMENT ON
TABLE <replaceable class="PARAMETER">object_name</replaceable> |
COLUMN <replaceable class="PARAMETER">table_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> |
AGGREGATE <replaceable class="PARAMETER">agg_name</replaceable> (<replaceable class="PARAMETER">agg_type</replaceable>) |
CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> |
DATABASE <replaceable class="PARAMETER">object_name</replaceable> |
DOMAIN <replaceable class="PARAMETER">object_name</replaceable> |
FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1_type</replaceable>, <replaceable class="PARAMETER">arg2_type</replaceable>, ...) |
......@@ -52,7 +53,7 @@ COMMENT ON
<variablelist>
<varlistentry>
<term><replaceable class="PARAMETER">object_name,
table_name.column_name, agg_name, func_name, op, rule_name, trigger_name</replaceable></term>
table_name.column_name, agg_name, constraint_name, func_name, op, rule_name, trigger_name</replaceable></term>
<listitem>
<para>
The name of the object to be be commented. Names of tables,
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_aggregate.sgml,v 1.18 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_aggregate.sgml,v 1.19 2002/07/12 18:43:12 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,7 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP AGGREGATE <replaceable class="PARAMETER">name</replaceable> ( <replaceable class="PARAMETER">type</replaceable> )
DROP AGGREGATE <replaceable class="PARAMETER">name</replaceable> ( <replaceable class="PARAMETER">type</replaceable> ) [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPAGGREGATE-1">
......@@ -54,6 +54,23 @@ DROP AGGREGATE <replaceable class="PARAMETER">name</replaceable> ( <replaceable
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the aggregate.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the aggregate if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v 1.6 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v 1.7 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -48,8 +48,8 @@ DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...] [ C
<term><literal>CASCADE</></term>
<listitem>
<para>
Automatically drop objects that depend on the domain. This
behavior is not currently supported.
Automatically drop objects that depend on the domain
(such as table columns).
</para>
</listitem>
</varlistentry>
......@@ -58,7 +58,8 @@ DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...] [ C
<term><literal>RESTRICT</></term>
<listitem>
<para>
Do not drop dependent objects. This is the default.
Refuse to drop the domain if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
......@@ -144,18 +145,13 @@ DROP DOMAIN box;
<refsect1 id="SQL-DROPDOMAIN-compatibility">
<title>Compatibility</title>
<para>
A <command>DROP DOMAIN</command> statement exists in SQL99. As with
most other <quote>drop</quote> commands, <command>DROP
DOMAIN</command> in SQL99 requires a <quote>drop behavior</quote>
clause to select between dropping all dependent objects or refusing
to drop if dependent objects exist:
<synopsis>
DROP DOMAIN <replaceable>name</replaceable> { CASCADE | RESTRICT }
</synopsis>
<productname>PostgreSQL</productname> accepts only the RESTRICT
option, and currently does not check for existence of dependent objects.
</para>
<refsect2 id="R2-SQL-DROPDOMAIN-sql92">
<title>
SQL92
</title>
<para></para>
</refsect2>
</refsect1>
<refsect1 id="SQL-DROPDOMAIN-see-also">
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_function.sgml,v 1.20 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_function.sgml,v 1.21 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,7 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">type</replaceable> [, ...] ] )
DROP FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">type</replaceable> [, ...] ] ) [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPFUNCTION-1">
......@@ -49,6 +49,24 @@ DROP FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the function
(such as operators or triggers).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the function if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......@@ -136,15 +154,8 @@ DROP FUNCTION sqrt(integer);
<title>Compatibility</title>
<para>
A <command>DROP FUNCTION</command> statement is defined in SQL99. One of its syntax forms is:
<synopsis>
DROP FUNCTION <replaceable class="parameter">name</replaceable> (<replaceable>arg</>, ...) { RESTRICT | CASCADE }
</synopsis>
where <literal>CASCADE</> specifies dropping all objects that
depend on the function and <literal>RESTRICT</literal> refuses to
drop the function if dependent objects exist.
A <command>DROP FUNCTION</command> statement is defined in SQL99. One of
its syntax forms is similar to PostgreSQL's.
</para>
</refsect1>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_index.sgml,v 1.15 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_index.sgml,v 1.16 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,7 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP INDEX <replaceable class="PARAMETER">index_name</replaceable> [, ...]
DROP INDEX <replaceable class="PARAMETER">index_name</replaceable> [, ...] [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPINDEX-1">
......@@ -41,6 +41,23 @@ DROP INDEX <replaceable class="PARAMETER">index_name</replaceable> [, ...]
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the index.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the index if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_language.sgml,v 1.14 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_language.sgml,v 1.15 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,7 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP [ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">name</replaceable>
DROP [ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">name</replaceable> [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPLANGUAGE-1">
......@@ -43,7 +43,26 @@ DROP [ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">name</replaceable>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the language
(such as functions in the language).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the language if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......@@ -112,14 +131,6 @@ ERROR: Language "<replaceable class="parameter">name</replaceable>" doesn't exis
<xref linkend="sql-createlanguage" endterm="sql-createlanguage-title">
for information on how to create procedural languages.
</para>
<para>
No checks are made if functions or trigger procedures registered
in this language still exist. To re-enable them without having
to drop and recreate all the functions, the pg_proc's prolang
attribute of the functions must be adjusted to the new object
ID of the recreated pg_language entry for the PL.
</para>
</refsect2>
</refsect1>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_operator.sgml,v 1.16 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_operator.sgml,v 1.17 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -22,7 +22,7 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP OPERATOR <replaceable class="PARAMETER">id</replaceable> ( <replaceable class="PARAMETER">lefttype</replaceable> | NONE , <replaceable class="PARAMETER">righttype</replaceable> | NONE )
DROP OPERATOR <replaceable class="PARAMETER">id</replaceable> ( <replaceable class="PARAMETER">lefttype</replaceable> | NONE , <replaceable class="PARAMETER">righttype</replaceable> | NONE ) [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPOPERATOR-1">
......@@ -60,6 +60,23 @@ DROP OPERATOR <replaceable class="PARAMETER">id</replaceable> ( <replaceable cla
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the operator.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the operator if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_rule.sgml,v 1.15 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_rule.sgml,v 1.16 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,7 @@ PostgreSQL documentation
<date>1998-09-22</date>
</refsynopsisdivinfo>
<synopsis>
DROP RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">relation</replaceable>
DROP RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">relation</replaceable> [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPRULE-1">
......@@ -50,7 +50,25 @@ DROP RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable clas
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the rule.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the rule if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_sequence.sgml,v 1.14 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_sequence.sgml,v 1.15 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,8 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP SEQUENCE <replaceable class="PARAMETER">name</replaceable> [, ...]
DROP SEQUENCE <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPSEQUENCE-1">
......@@ -75,7 +76,25 @@ ERROR: sequence "<replaceable class="parameter">name</replaceable>" does not exi
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the sequence.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the sequence if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
</refsynopsisdiv>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_table.sgml,v 1.15 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_table.sgml,v 1.16 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,8 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP TABLE <replaceable class="PARAMETER">name</replaceable> [, ...]
DROP TABLE <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPTABLE-1">
......@@ -41,6 +42,24 @@ DROP TABLE <replaceable class="PARAMETER">name</replaceable> [, ...]
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the table
(such as views).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the table if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......@@ -136,44 +155,11 @@ DROP TABLE films, distributors;
</title>
<refsect2 id="R2-SQL-DROPTABLE-4">
<refsect2info>
<date>1998-09-22</date>
</refsect2info>
<title>
SQL92
</title>
<para>
SQL92 specifies some additional capabilities for DROP TABLE:
</para>
<synopsis>
DROP TABLE <replaceable class="parameter">table</replaceable> { RESTRICT | CASCADE }
</synopsis>
<variablelist>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Ensures that only a table with no dependent views or
integrity constraints can be destroyed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Any referencing views or integrity constraints
will also be dropped.
</para>
</listitem>
</varlistentry>
</variablelist>
<tip>
<para>
At present, to remove a referencing view you must drop
it explicitly.
</para>
</tip>
</refsect2>
</refsect1>
</refentry>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_trigger.sgml,v 1.12 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_trigger.sgml,v 1.13 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,7 @@ PostgreSQL documentation
<date>1998-09-22</date>
</refsynopsisdivinfo>
<synopsis>
DROP TRIGGER <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table</replaceable>
DROP TRIGGER <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table</replaceable> [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPTRIGGER-1">
......@@ -50,6 +50,23 @@ DROP TRIGGER <replaceable class="PARAMETER">name</replaceable> ON <replaceable c
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the trigger.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the trigger if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_type.sgml,v 1.17 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_type.sgml,v 1.18 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,8 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP TYPE <replaceable class="PARAMETER">typename</replaceable> [, ...]
DROP TYPE <replaceable class="PARAMETER">typename</replaceable> [, ...] [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPTYPE-1">
......@@ -41,6 +42,24 @@ DROP TYPE <replaceable class="PARAMETER">typename</replaceable> [, ...]
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the type
(such as table columns, functions, operators, etc).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the type if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......@@ -75,6 +94,7 @@ ERROR: RemoveType: type '<replaceable class="parameter">typename</replaceable>'
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
</refsynopsisdiv>
......@@ -132,19 +152,6 @@ DROP TYPE box;
<refsect1 id="SQL-DROPTYPE-compatibility">
<title>Compatibility</title>
<para>
A <command>DROP TYPE</command> statement exists in SQL99. As with
most other <quote>drop</quote> commands, <command>DROP
TYPE</command> in SQL99 requires a <quote>drop behavior</quote>
clause to select between dropping all dependent objects or refusing
to drop if dependent objects exist:
<synopsis>
DROP TYPE <replaceable>name</replaceable> { CASCADE | RESTRICT }
</synopsis>
<productname>PostgreSQL</productname> currently ignores
dependencies altogether.
</para>
<para>
Note that the <command>CREATE TYPE</command> command and the data
type extension mechanisms in <productname>PostgreSQL</productname>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_view.sgml,v 1.14 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_view.sgml,v 1.15 2002/07/12 18:43:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -21,7 +21,7 @@ PostgreSQL documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP VIEW <replaceable class="PARAMETER">name</replaceable> [, ...]
DROP VIEW <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
</synopsis>
<refsect2 id="R2-SQL-DROPVIEW-1">
......@@ -42,7 +42,26 @@ DROP VIEW <replaceable class="PARAMETER">name</replaceable> [, ...]
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the view
(such as other views).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the view if there are any dependent objects.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
......@@ -134,58 +153,7 @@ DROP VIEW kinds;
SQL92
</title>
<para>
<acronym>SQL92</acronym> specifies some additional capabilities for
<command>DROP VIEW</command>:
<synopsis>
DROP VIEW <replaceable class="parameter">view</replaceable> { RESTRICT | CASCADE }
</synopsis>
</para>
<refsect3 id="R3-SQL-DROPVIEW-1">
<refsect3info>
<date>1998-09-22</date>
</refsect3info>
<title>
Inputs
</title>
<para>
<variablelist>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Ensures that only a view with no dependent views or
integrity constraints can be destroyed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Any referencing views and integrity constraints
will be dropped as well.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect3>
<refsect3 id="R3-SQL-DROPVIEW-2">
<refsect3info>
<date>1998-09-22</date>
</refsect3info>
<title>
Notes
</title>
<para>
At present, to remove a referencing view from a
<productname>PostgreSQL</productname> database,
you must drop it explicitly.
</para>
</refsect3>
</refsect2>
</refsect1>
</refentry>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.139 2002/06/11 15:32:33 thomas Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.140 2002/07/12 18:43:12 tgl Exp $
-->
<appendix id="release">
......@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
Most forms of DROP now support RESTRICT and CASCADE options
Recursive SQL functions can be defined
User-defined procedural languages can register a validator function to check new functions as they are created
Functions can be executed with the privileges of the owner
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.48 2002/06/20 20:29:25 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.49 2002/07/12 18:43:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -240,7 +240,8 @@ Boot_DeclareIndexStmt:
DefineIndex(makeRangeVar(NULL, LexIDStr($5)),
LexIDStr($3),
LexIDStr($7),
$9, false, false, NULL, NIL);
$9,
false, false, false, NULL, NIL);
do_end();
}
;
......@@ -253,7 +254,8 @@ Boot_DeclareUniqueIndexStmt:
DefineIndex(makeRangeVar(NULL, LexIDStr($6)),
LexIDStr($4),
LexIDStr($8),
$10, true, false, NULL, NIL);
$10,
true, false, false, NULL, NIL);
do_end();
}
;
......
......@@ -2,7 +2,7 @@
#
# Makefile for backend/catalog
#
# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.40 2002/07/11 07:39:27 ishii Exp $
# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.41 2002/07/12 18:43:13 tgl Exp $
#
#-------------------------------------------------------------------------
......@@ -10,9 +10,9 @@ subdir = src/backend/catalog
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \
pg_aggregate.o pg_largeobject.o pg_namespace.o \
pg_operator.o pg_proc.o pg_type.o pg_conversion.o
OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o \
pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_type.o
BKIFILES = postgres.bki postgres.description
......@@ -27,12 +27,12 @@ SUBSYS.o: $(OBJS)
POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_proc.h pg_type.h pg_attribute.h pg_class.h \
pg_attrdef.h pg_relcheck.h pg_inherits.h pg_index.h \
pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h \
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h \
pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
indexing.h \
pg_depend.h indexing.h \
)
pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
......
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.181 2002/06/20 20:29:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.182 2002/07/12 18:43:13 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -29,14 +29,15 @@
#include "bootstrap/bootstrap.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_index.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "executor/executor.h"
#include "miscadmin.h"
#include "optimizer/clauses.h"
......@@ -535,6 +536,7 @@ index_create(Oid heapRelationId,
Oid accessMethodObjectId,
Oid *classObjectId,
bool primary,
bool isconstraint,
bool allow_system_table_mods)
{
Relation heapRelation;
......@@ -543,6 +545,7 @@ index_create(Oid heapRelationId,
bool shared_relation;
Oid namespaceId;
Oid indexoid;
int i;
SetReindexProcessing(false);
......@@ -660,7 +663,89 @@ index_create(Oid heapRelationId,
classObjectId, primary);
/*
* fill in the index strategy structure with information from the
* Register constraint and dependencies for the index.
*
* If the index is from a CONSTRAINT clause, construct a pg_constraint
* entry. The index is then linked to the constraint, which in turn is
* linked to the table. If it's not a CONSTRAINT, make the dependency
* directly on the table.
*
* During bootstrap we can't register any dependencies, and we don't
* try to make a constraint either.
*/
if (!IsBootstrapProcessingMode())
{
ObjectAddress myself,
referenced;
myself.classId = RelOid_pg_class;
myself.objectId = indexoid;
myself.objectSubId = 0;
if (isconstraint)
{
char constraintType;
Oid conOid;
if (primary)
constraintType = CONSTRAINT_PRIMARY;
else if (indexInfo->ii_Unique)
constraintType = CONSTRAINT_UNIQUE;
else
{
elog(ERROR, "index_create: constraint must be PRIMARY or UNIQUE");
constraintType = 0; /* keep compiler quiet */
}
conOid = CreateConstraintEntry(indexRelationName,
namespaceId,
constraintType,
false, /* isDeferrable */
false, /* isDeferred */
heapRelationId,
indexInfo->ii_KeyAttrNumbers,
indexInfo->ii_NumIndexAttrs,
InvalidOid, /* no domain */
InvalidOid, /* no foreign key */
NULL,
0,
' ',
' ',
' ',
NULL, /* Constraint Bin & Src */
NULL);
referenced.classId = get_system_catalog_relid(ConstraintRelationName);
referenced.objectId = conOid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
}
else
{
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
{
referenced.classId = RelOid_pg_class;
referenced.objectId = heapRelationId;
referenced.objectSubId = indexInfo->ii_KeyAttrNumbers[i];
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
}
}
/* Store the dependency on the function (if appropriate) */
if (OidIsValid(indexInfo->ii_FuncOid))
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = indexInfo->ii_FuncOid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
}
/*
* Fill in the index strategy structure with information from the
* catalogs. First we must advance the command counter so that we
* will see the newly-entered index catalog tuples.
*/
......@@ -691,11 +776,11 @@ index_create(Oid heapRelationId,
return indexoid;
}
/* ----------------------------------------------------------------
*
/*
* index_drop
*
* ----------------------------------------------------------------
* NOTE: this routine should now only be called through performDeletion(),
* else associated dependencies won't be cleaned up.
*/
void
index_drop(Oid indexId)
......@@ -730,17 +815,6 @@ index_drop(Oid indexId)
userIndexRelation = index_open(indexId);
LockRelation(userIndexRelation, AccessExclusiveLock);
/*
* Note: unlike heap_drop_with_catalog, we do not need to prevent
* deletion of system indexes here; that's checked for upstream. If we
* did check it here, deletion of TOAST tables would fail...
*/
/*
* fix DESCRIPTION relation
*/
DeleteComments(indexId, RelOid_pg_class);
/*
* fix RELATION relation
*/
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.95 2002/07/11 07:39:27 ishii Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.96 2002/07/12 18:43:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -45,10 +45,14 @@ char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
{AttrDefaultIndex};
char *Name_pg_class_indices[Num_pg_class_indices] =
{ClassNameNspIndex, ClassOidIndex};
char *Name_pg_constraint_indices[Num_pg_constraint_indices] =
{ConstraintNameNspIndex, ConstraintOidIndex, ConstraintRelidIndex};
char *Name_pg_conversion_indices[Num_pg_conversion_indices] =
{ConversionNameNspIndex, ConversionDefaultIndex};
char *Name_pg_database_indices[Num_pg_database_indices] =
{DatabaseNameIndex, DatabaseOidIndex};
char *Name_pg_depend_indices[Num_pg_depend_indices] =
{DependDependerIndex, DependReferenceIndex};
char *Name_pg_group_indices[Num_pg_group_indices] =
{GroupNameIndex, GroupSysidIndex};
char *Name_pg_index_indices[Num_pg_index_indices] =
......@@ -67,8 +71,6 @@ char *Name_pg_operator_indices[Num_pg_operator_indices] =
{OperatorOidIndex, OperatorNameNspIndex};
char *Name_pg_proc_indices[Num_pg_proc_indices] =
{ProcedureOidIndex, ProcedureNameNspIndex};
char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] =
{RelCheckIndex};
char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] =
{RewriteOidIndex, RewriteRelRulenameIndex};
char *Name_pg_shadow_indices[Num_pg_shadow_indices] =
......
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.23 2002/06/20 20:29:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.24 2002/07/12 18:43:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -23,6 +23,7 @@
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/namespace.h"
#include "catalog/pg_inherits.h"
......@@ -128,25 +129,10 @@ static Oid mySpecialNamespace = InvalidOid;
char *namespace_search_path = NULL;
/*
* Deletion ordering constraint item.
*/
typedef struct DelConstraint
{
Oid referencer; /* table to delete first */
Oid referencee; /* table to delete second */
int pred; /* workspace for TopoSortRels */
struct DelConstraint *link; /* workspace for TopoSortRels */
} DelConstraint;
/* Local functions */
static void recomputeNamespacePath(void);
static void InitTempTableNamespace(void);
static void RemoveTempRelations(Oid tempNamespaceId);
static List *FindTempRelations(Oid tempNamespaceId);
static List *FindDeletionConstraints(List *relOids);
static List *TopoSortRels(List *relOids, List *constraintList);
static void RemoveTempRelationsCallback(void);
static void NamespaceCallback(Datum arg, Oid relid);
......@@ -1531,56 +1517,22 @@ AtEOXact_Namespace(bool isCommit)
static void
RemoveTempRelations(Oid tempNamespaceId)
{
List *tempRelList;
List *constraintList;
List *lptr;
/* Get a list of relations to delete */
tempRelList = FindTempRelations(tempNamespaceId);
if (tempRelList == NIL)
return; /* nothing to do */
/* If more than one, sort them to respect any deletion-order constraints */
if (length(tempRelList) > 1)
{
constraintList = FindDeletionConstraints(tempRelList);
if (constraintList != NIL)
tempRelList = TopoSortRels(tempRelList, constraintList);
}
/* Scan the list and delete all entries */
foreach(lptr, tempRelList)
{
Oid reloid = (Oid) lfirsti(lptr);
heap_drop_with_catalog(reloid, true);
/*
* Advance cmd counter to make catalog changes visible, in case
* a later entry depends on this one.
*/
CommandCounterIncrement();
}
}
/*
* Find all relations in the specified temp namespace.
*
* Returns a list of relation OIDs.
*/
static List *
FindTempRelations(Oid tempNamespaceId)
{
List *tempRelList = NIL;
Relation pgclass;
HeapScanDesc scan;
HeapTuple tuple;
ScanKeyData key;
ObjectAddress object;
/*
* Scan pg_class to find all the relations in the target namespace.
* Ignore indexes, though, on the assumption that they'll go away
* when their tables are deleted.
*
* NOTE: if there are deletion constraints between temp relations,
* then our CASCADE delete call may cause as-yet-unvisited objects
* to go away. This is okay because we are using SnapshotNow; when
* the scan does reach those pg_class tuples, they'll be ignored as
* already deleted.
*/
ScanKeyEntryInitialize(&key, 0x0,
Anum_pg_class_relnamespace,
......@@ -1597,7 +1549,10 @@ FindTempRelations(Oid tempNamespaceId)
case RELKIND_RELATION:
case RELKIND_SEQUENCE:
case RELKIND_VIEW:
tempRelList = lconsi(tuple->t_data->t_oid, tempRelList);
object.classId = RelOid_pg_class;
object.objectId = tuple->t_data->t_oid;
object.objectSubId = 0;
performDeletion(&object, DROP_CASCADE);
break;
default:
break;
......@@ -1606,164 +1561,6 @@ FindTempRelations(Oid tempNamespaceId)
heap_endscan(scan);
heap_close(pgclass, AccessShareLock);
return tempRelList;
}
/*
* Find deletion-order constraints involving the given relation OIDs.
*
* Returns a list of DelConstraint objects.
*/
static List *
FindDeletionConstraints(List *relOids)
{
List *constraintList = NIL;
Relation inheritsrel;
HeapScanDesc scan;
HeapTuple tuple;
/*
* Scan pg_inherits to find parents and children that are in the list.
*/
inheritsrel = heap_openr(InheritsRelationName, AccessShareLock);
scan = heap_beginscan(inheritsrel, SnapshotNow, 0, NULL);
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
Oid inhrelid = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid;
Oid inhparent = ((Form_pg_inherits) GETSTRUCT(tuple))->inhparent;
if (intMember(inhrelid, relOids) && intMember(inhparent, relOids))
{
DelConstraint *item;
item = (DelConstraint *) palloc(sizeof(DelConstraint));
item->referencer = inhrelid;
item->referencee = inhparent;
constraintList = lcons(item, constraintList);
}
}
heap_endscan(scan);
heap_close(inheritsrel, AccessShareLock);
return constraintList;
}
/*
* TopoSortRels -- topological sort of a list of rels to delete
*
* This is a lot simpler and slower than, for example, the topological sort
* algorithm shown in Knuth's Volume 1. However, we are not likely to be
* working with more than a few constraints, so the apparent slowness of the
* algorithm won't really matter.
*/
static List *
TopoSortRels(List *relOids, List *constraintList)
{
int queue_size = length(relOids);
Oid *rels;
int *beforeConstraints;
DelConstraint **afterConstraints;
List *resultList = NIL;
List *lptr;
int i,
j,
k,
last;
/* Allocate workspace */
rels = (Oid *) palloc(queue_size * sizeof(Oid));
beforeConstraints = (int *) palloc(queue_size * sizeof(int));
afterConstraints = (DelConstraint **)
palloc(queue_size * sizeof(DelConstraint*));
/* Build an array of the target relation OIDs */
i = 0;
foreach(lptr, relOids)
{
rels[i++] = (Oid) lfirsti(lptr);
}
/*
* Scan the constraints, and for each rel in the array, generate a
* count of the number of constraints that say it must be before
* something else, plus a list of the constraints that say it must be
* after something else. The count for the j'th rel is stored in
* beforeConstraints[j], and the head of its list in
* afterConstraints[j]. Each constraint stores its list link in
* its link field (note any constraint will be in just one list).
* The array index for the before-rel of each constraint is
* remembered in the constraint's pred field.
*/
MemSet(beforeConstraints, 0, queue_size * sizeof(int));
MemSet(afterConstraints, 0, queue_size * sizeof(DelConstraint*));
foreach(lptr, constraintList)
{
DelConstraint *constraint = (DelConstraint *) lfirst(lptr);
Oid rel;
/* Find the referencer rel in the array */
rel = constraint->referencer;
for (j = queue_size; --j >= 0;)
{
if (rels[j] == rel)
break;
}
Assert(j >= 0); /* should have found a match */
/* Find the referencee rel in the array */
rel = constraint->referencee;
for (k = queue_size; --k >= 0;)
{
if (rels[k] == rel)
break;
}
Assert(k >= 0); /* should have found a match */
beforeConstraints[j]++; /* referencer must come before */
/* add this constraint to list of after-constraints for referencee */
constraint->pred = j;
constraint->link = afterConstraints[k];
afterConstraints[k] = constraint;
}
/*--------------------
* Now scan the rels array backwards. At each step, output the
* last rel that has no remaining before-constraints, and decrease
* the beforeConstraints count of each of the rels it was constrained
* against. (This is the right order since we are building the result
* list back-to-front.)
* i = counter for number of rels left to output
* j = search index for rels[]
* dc = temp for scanning constraint list for rel j
* last = last valid index in rels (avoid redundant searches)
*--------------------
*/
last = queue_size - 1;
for (i = queue_size; --i >= 0;)
{
DelConstraint *dc;
/* Find next candidate to output */
while (rels[last] == InvalidOid)
last--;
for (j = last; j >= 0; j--)
{
if (rels[j] != InvalidOid && beforeConstraints[j] == 0)
break;
}
/* If no available candidate, topological sort fails */
if (j < 0)
elog(ERROR, "TopoSortRels: failed to find a workable deletion ordering");
/* Output candidate, and mark it done by zeroing rels[] entry */
resultList = lconsi(rels[j], resultList);
rels[j] = InvalidOid;
/* Update beforeConstraints counts of its predecessors */
for (dc = afterConstraints[j]; dc; dc = dc->link)
beforeConstraints[dc->pred]--;
}
/* Done */
return resultList;
}
/*
......
This diff is collapsed.
/*-------------------------------------------------------------------------
*
* pg_depend.c
* routines to support manipulation of the pg_depend relation
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.1 2002/07/12 18:43:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/dependency.h"
#include "catalog/pg_depend.h"
#include "miscadmin.h"
#include "utils/fmgroids.h"
static bool isObjectPinned(const ObjectAddress *object, Relation rel);
/*
* Record a dependency between 2 objects via their respective objectAddress.
* The first argument is the dependent object, the second the one it
* references.
*
* This simply creates an entry in pg_depend, without any other processing.
*/
void
recordDependencyOn(const ObjectAddress *depender,
const ObjectAddress *referenced,
DependencyType behavior)
{
Relation dependDesc;
HeapTuple tup;
int i;
char nulls[Natts_pg_depend];
Datum values[Natts_pg_depend];
Relation idescs[Num_pg_depend_indices];
/*
* During bootstrap, do nothing since pg_depend may not exist yet.
* initdb will fill in appropriate pg_depend entries after bootstrap.
*/
if (IsBootstrapProcessingMode())
return;
dependDesc = heap_openr(DependRelationName, RowExclusiveLock);
/*
* If the referenced object is pinned by the system, there's no real
* need to record dependencies on it. This saves lots of space in
* pg_depend, so it's worth the time taken to check.
*/
if (!isObjectPinned(referenced, dependDesc))
{
/*
* Record the Dependency. Note we don't bother to check for
* duplicate dependencies; there's no harm in them.
*/
for (i = 0; i < Natts_pg_depend; ++i)
{
nulls[i] = ' ';
values[i] = (Datum) 0;
}
values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
values[Anum_pg_depend_deptype -1] = CharGetDatum((char) behavior);
tup = heap_formtuple(dependDesc->rd_att, values, nulls);
simple_heap_insert(dependDesc, tup);
/*
* Keep indices current
*/
CatalogOpenIndices(Num_pg_depend_indices, Name_pg_depend_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_depend_indices, dependDesc, tup);
CatalogCloseIndices(Num_pg_depend_indices, idescs);
}
heap_close(dependDesc, RowExclusiveLock);
}
/*
* isObjectPinned()
*
* Test if an object is required for basic database functionality.
* Caller must already have opened pg_depend.
*
* The passed subId, if any, is ignored; we assume that only whole objects
* are pinned (and that this implies pinning their components).
*/
static bool
isObjectPinned(const ObjectAddress *object, Relation rel)
{
bool ret = false;
SysScanDesc scan;
HeapTuple tup;
ScanKeyData key[2];
ScanKeyEntryInitialize(&key[0], 0x0,
Anum_pg_depend_refclassid, F_OIDEQ,
ObjectIdGetDatum(object->classId));
ScanKeyEntryInitialize(&key[1], 0x0,
Anum_pg_depend_refobjid, F_OIDEQ,
ObjectIdGetDatum(object->objectId));
scan = systable_beginscan(rel, DependReferenceIndex, true,
SnapshotNow, 2, key);
/*
* Since we won't generate additional pg_depend entries for pinned
* objects, there can be at most one entry referencing a pinned
* object. Hence, it's sufficient to look at the first returned
* tuple; we don't need to loop.
*/
tup = systable_getnext(scan);
if (HeapTupleIsValid(tup))
{
Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
if (foundDep->deptype == DEPENDENCY_PIN)
ret = true;
}
systable_endscan(scan);
return ret;
}
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.72 2002/06/20 20:29:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.73 2002/07/12 18:43:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -16,6 +16,7 @@
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
......@@ -166,6 +167,8 @@ TypeCreate(const char *typeName,
NameData name;
TupleDesc tupDesc;
int i;
ObjectAddress myself,
referenced;
/*
* validate size specifications: either positive (fixed-length) or -1
......@@ -298,6 +301,77 @@ TypeCreate(const char *typeName,
CatalogCloseIndices(Num_pg_type_indices, idescs);
}
/*
* Create dependencies
*/
myself.classId = RelOid_pg_type;
myself.objectId = typeObjectId;
myself.objectSubId = 0;
/* Normal dependencies on the I/O functions */
referenced.classId = RelOid_pg_proc;
referenced.objectId = inputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
referenced.classId = RelOid_pg_proc;
referenced.objectId = outputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
if (receiveProcedure != inputProcedure)
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = receiveProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (sendProcedure != outputProcedure)
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = sendProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/*
* If the type is a rowtype for a relation, mark it as internally
* dependent on the relation. This allows it to be auto-dropped
* when the relation is, and not otherwise.
*/
if (OidIsValid(relationOid))
{
referenced.classId = RelOid_pg_class;
referenced.objectId = relationOid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
}
/*
* If the type is an array type, mark it auto-dependent on the
* base type. (This is a compromise between the typical case where the
* array type is automatically generated and the case where it is manually
* created: we'd prefer INTERNAL for the former case and NORMAL for the
* latter.)
*/
if (OidIsValid(elementType))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = elementType;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
}
/* Normal dependency from a domain to its base type. */
if (OidIsValid(baseType))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = baseType;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/*
* finish up
*/
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v 1.2 2002/04/27 03:45:00 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v 1.3 2002/07/12 18:43:15 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
......@@ -24,10 +24,10 @@
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/namespace.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h"
#include "commands/comment.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
......@@ -141,13 +141,19 @@ DefineAggregate(List *names, List *parameters)
}
/*
* RemoveAggregate
* Deletes an aggregate.
*/
void
RemoveAggregate(List *aggName, TypeName *aggType)
RemoveAggregate(RemoveAggrStmt *stmt)
{
Relation relation;
HeapTuple tup;
List *aggName = stmt->aggname;
TypeName *aggType = stmt->aggtype;
Oid basetypeID;
Oid procOid;
HeapTuple tup;
ObjectAddress object;
/*
* if a basetype is passed in, then attempt to find an aggregate for
......@@ -164,8 +170,9 @@ RemoveAggregate(List *aggName, TypeName *aggType)
procOid = find_aggregate_func("RemoveAggregate", aggName, basetypeID);
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
/*
* Find the function tuple, do permissions and validity checks
*/
tup = SearchSysCache(PROCOID,
ObjectIdGetDatum(procOid),
0, 0, 0);
......@@ -179,30 +186,16 @@ RemoveAggregate(List *aggName, TypeName *aggType)
GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(aggName));
/* Delete any comments associated with this function */
DeleteComments(procOid, RelationGetRelid(relation));
/* Remove the pg_proc tuple */
simple_heap_delete(relation, &tup->t_self);
/* find_aggregate_func already checked it is an aggregate */
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock);
/* Remove the pg_aggregate tuple */
relation = heap_openr(AggregateRelationName, RowExclusiveLock);
tup = SearchSysCache(AGGFNOID,
ObjectIdGetDatum(procOid),
0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveAggregate: couldn't find pg_aggregate tuple for %s",
NameListToString(aggName));
simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup);
/*
* Do the deletion
*/
object.classId = RelOid_pg_proc;
object.objectId = procOid;
object.objectSubId = 0;
heap_close(relation, RowExclusiveLock);
performDeletion(&object, stmt->behavior);
}
......@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.82 2002/06/20 20:29:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.83 2002/07/12 18:43:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -24,6 +24,7 @@
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/pg_index.h"
......@@ -64,6 +65,7 @@ cluster(RangeVar *oldrelation, char *oldindexname)
OldIndex;
char NewHeapName[NAMEDATALEN];
char NewIndexName[NAMEDATALEN];
ObjectAddress object;
/*
* We grab exclusive access to the target rel and index for the
......@@ -119,9 +121,14 @@ cluster(RangeVar *oldrelation, char *oldindexname)
CommandCounterIncrement();
/* Destroy old heap (along with its index) and rename new. */
heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods);
object.classId = RelOid_pg_class;
object.objectId = OIDOldHeap;
object.objectSubId = 0;
CommandCounterIncrement();
/* XXX better to use DROP_CASCADE here? */
performDeletion(&object, DROP_RESTRICT);
/* performDeletion does CommandCounterIncrement at end */
renamerel(OIDNewHeap, oldrelation->relname);
......@@ -198,6 +205,7 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, const char *NewIndexName)
OldIndex->rd_rel->relam,
OldIndex->rd_index->indclass,
OldIndex->rd_index->indisprimary,
false, /* XXX losing constraint status */
allowSystemTableMods);
setRelhasindex(OIDNewHeap, true,
......
......@@ -7,7 +7,7 @@
* Copyright (c) 1996-2001, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.49 2002/06/20 20:51:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.50 2002/07/12 18:43:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -225,38 +225,45 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
}
/*
* DeleteComments --
* DeleteComments -- remove comments for an object
*
* This routine is used to purge all comments associated with an object,
* regardless of their objsubid. It is called, for example, when a relation
* is destroyed.
* If subid is nonzero then only comments matching it will be removed.
* If subid is zero, all comments matching the oid/classoid will be removed
* (this corresponds to deleting a whole object).
*/
void
DeleteComments(Oid oid, Oid classoid)
DeleteComments(Oid oid, Oid classoid, int32 subid)
{
Relation description;
ScanKeyData skey[2];
ScanKeyData skey[3];
int nkeys;
SysScanDesc sd;
HeapTuple oldtuple;
/* Use the index to search for all matching old tuples */
ScanKeyEntryInitialize(&skey[0],
(bits16) 0x0,
(AttrNumber) 1,
(RegProcedure) F_OIDEQ,
ScanKeyEntryInitialize(&skey[0], 0x0,
Anum_pg_description_objoid, F_OIDEQ,
ObjectIdGetDatum(oid));
ScanKeyEntryInitialize(&skey[1],
(bits16) 0x0,
(AttrNumber) 2,
(RegProcedure) F_OIDEQ,
ScanKeyEntryInitialize(&skey[1], 0x0,
Anum_pg_description_classoid, F_OIDEQ,
ObjectIdGetDatum(classoid));
if (subid != 0)
{
ScanKeyEntryInitialize(&skey[2], 0x0,
Anum_pg_description_objsubid, F_INT4EQ,
Int32GetDatum(subid));
nkeys = 3;
}
else
nkeys = 2;
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
sd = systable_beginscan(description, DescriptionObjIndex, true,
SnapshotNow, 2, skey);
SnapshotNow, nkeys, skey);
while ((oldtuple = systable_getnext(sd)) != NULL)
{
......@@ -266,7 +273,7 @@ DeleteComments(Oid oid, Oid classoid)
/* Done */
systable_endscan(sd);
heap_close(description, NoLock);
heap_close(description, RowExclusiveLock);
}
/*
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.95 2002/06/20 20:29:27 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.96 2002/07/12 18:43:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -456,8 +456,13 @@ dropdb(const char *dbname)
heap_endscan(pgdbscan);
/* Delete any comments associated with the database */
DeleteComments(db_id, RelationGetRelid(pgdbrel));
/*
* Delete any comments associated with the database
*
* NOTE: this is probably dead code since any such comments should have
* been in that database, not mine.
*/
DeleteComments(db_id, RelationGetRelid(pgdbrel), 0);
/*
* Close pg_database, but keep exclusive lock till commit to ensure
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.7 2002/06/20 20:29:27 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.8 2002/07/12 18:43:16 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
......@@ -33,11 +33,11 @@
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/namespace.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "optimizer/cost.h"
......@@ -532,25 +532,22 @@ CreateFunction(CreateFunctionStmt *stmt)
/*
* RemoveFunction
* Deletes a function.
*
* Exceptions:
* BadArg if name is invalid.
* "ERROR" if function nonexistent.
* ...
*/
void
RemoveFunction(List *functionName, /* function name to be removed */
List *argTypes) /* list of TypeName nodes */
RemoveFunction(RemoveFuncStmt *stmt)
{
List *functionName = stmt->funcname;
List *argTypes = stmt->args; /* list of TypeName nodes */
Oid funcOid;
Relation relation;
HeapTuple tup;
ObjectAddress object;
/*
* Find the function, do permissions and validity checks
*/
funcOid = LookupFuncNameTypeNames(functionName, argTypes,
true, "RemoveFunction");
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
tup = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcOid),
0, 0, 0);
......@@ -576,12 +573,69 @@ RemoveFunction(List *functionName, /* function name to be removed */
NameListToString(functionName));
}
/* Delete any comments associated with this function */
DeleteComments(funcOid, RelationGetRelid(relation));
ReleaseSysCache(tup);
/*
* Do the deletion
*/
object.classId = RelOid_pg_proc;
object.objectId = funcOid;
object.objectSubId = 0;
performDeletion(&object, stmt->behavior);
}
/*
* Guts of function deletion.
*
* Note: this is also used for aggregate deletion, since the OIDs of
* both functions and aggregates point to pg_proc.
*/
void
RemoveFunctionById(Oid funcOid)
{
Relation relation;
HeapTuple tup;
bool isagg;
/*
* Delete the pg_proc tuple.
*/
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
tup = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcOid),
0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveFunctionById: couldn't find tuple for function %u",
funcOid);
isagg = ((Form_pg_proc) GETSTRUCT(tup))->proisagg;
simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock);
/*
* If there's a pg_aggregate tuple, delete that too.
*/
if (isagg)
{
relation = heap_openr(AggregateRelationName, RowExclusiveLock);
tup = SearchSysCache(AGGFNOID,
ObjectIdGetDatum(funcOid),
0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveFunctionById: couldn't find pg_aggregate tuple for %u",
funcOid);
simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock);
}
}
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.76 2002/07/01 15:27:45 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.77 2002/07/12 18:43:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -18,6 +18,7 @@
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_opclass.h"
......@@ -68,6 +69,7 @@ DefineIndex(RangeVar *heapRelation,
List *attributeList,
bool unique,
bool primary,
bool isconstraint,
Expr *predicate,
List *rangetable)
{
......@@ -208,7 +210,7 @@ DefineIndex(RangeVar *heapRelation,
index_create(relationId, indexRelationName,
indexInfo, accessMethodId, classObjectId,
primary, allowSystemTableMods);
primary, isconstraint, allowSystemTableMods);
/*
* We update the relation's pg_class tuple even if it already has
......@@ -566,6 +568,7 @@ RemoveIndex(RangeVar *relation, DropBehavior behavior)
{
Oid indOid;
HeapTuple tuple;
ObjectAddress object;
indOid = RangeVarGetRelid(relation, false);
tuple = SearchSysCache(RELOID,
......@@ -580,7 +583,11 @@ RemoveIndex(RangeVar *relation, DropBehavior behavior)
ReleaseSysCache(tuple);
index_drop(indOid);
object.classId = RelOid_pg_class;
object.objectId = indOid;
object.objectSubId = 0;
performDeletion(&object, behavior);
}
/*
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/operatorcmds.c,v 1.4 2002/07/01 15:27:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/operatorcmds.c,v 1.5 2002/07/12 18:43:16 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
......@@ -36,9 +36,9 @@
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/namespace.h"
#include "catalog/pg_operator.h"
#include "commands/comment.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "parser/parse_oper.h"
......@@ -217,15 +217,13 @@ RemoveOperator(RemoveOperStmt *stmt)
TypeName *typeName1 = (TypeName *) lfirst(stmt->args);
TypeName *typeName2 = (TypeName *) lsecond(stmt->args);
Oid operOid;
Relation relation;
HeapTuple tup;
ObjectAddress object;
operOid = LookupOperNameTypeNames(operatorName, typeName1, typeName2,
"RemoveOperator");
relation = heap_openr(OperatorRelationName, RowExclusiveLock);
tup = SearchSysCacheCopy(OPEROID,
tup = SearchSysCache(OPEROID,
ObjectIdGetDatum(operOid),
0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */
......@@ -238,11 +236,39 @@ RemoveOperator(RemoveOperStmt *stmt)
GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(operatorName));
/* Delete any comments associated with this operator */
DeleteComments(operOid, RelationGetRelid(relation));
ReleaseSysCache(tup);
/*
* Do the deletion
*/
object.classId = get_system_catalog_relid(OperatorRelationName);
object.objectId = operOid;
object.objectSubId = 0;
performDeletion(&object, stmt->behavior);
}
/*
* Guts of operator deletion.
*/
void
RemoveOperatorById(Oid operOid)
{
Relation relation;
HeapTuple tup;
relation = heap_openr(OperatorRelationName, RowExclusiveLock);
tup = SearchSysCache(OPEROID,
ObjectIdGetDatum(operOid),
0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveOperatorById: failed to find tuple for operator %u",
operOid);
simple_heap_delete(relation, &tup->t_self);
heap_freetuple(tup);
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock);
}
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.34 2002/06/20 20:29:27 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.35 2002/07/12 18:43:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -17,6 +17,7 @@
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_language.h"
......@@ -140,7 +141,7 @@ DropProceduralLanguage(DropPLangStmt *stmt)
{
char languageName[NAMEDATALEN];
HeapTuple langTup;
Relation rel;
ObjectAddress object;
/*
* Check permission
......@@ -155,10 +156,8 @@ DropProceduralLanguage(DropPLangStmt *stmt)
*/
case_translate_language_name(stmt->plname, languageName);
rel = heap_openr(LanguageRelationName, RowExclusiveLock);
langTup = SearchSysCacheCopy(LANGNAME,
PointerGetDatum(languageName),
langTup = SearchSysCache(LANGNAME,
CStringGetDatum(languageName),
0, 0, 0);
if (!HeapTupleIsValid(langTup))
elog(ERROR, "Language %s doesn't exist", languageName);
......@@ -167,8 +166,39 @@ DropProceduralLanguage(DropPLangStmt *stmt)
elog(ERROR, "Language %s isn't a created procedural language",
languageName);
object.classId = get_system_catalog_relid(LanguageRelationName);
object.objectId = langTup->t_data->t_oid;
object.objectSubId = 0;
ReleaseSysCache(langTup);
/*
* Do the deletion
*/
performDeletion(&object, stmt->behavior);
}
/*
* Guts of language dropping.
*/
void
DropProceduralLanguageById(Oid langOid)
{
Relation rel;
HeapTuple langTup;
rel = heap_openr(LanguageRelationName, RowExclusiveLock);
langTup = SearchSysCache(LANGOID,
ObjectIdGetDatum(langOid),
0, 0, 0);
if (!HeapTupleIsValid(langTup))
elog(ERROR, "DropProceduralLanguageById: language %u not found",
langOid);
simple_heap_delete(rel, &langTup->t_self);
heap_freetuple(langTup);
ReleaseSysCache(langTup);
heap_close(rel, RowExclusiveLock);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -6,13 +6,14 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: view.c,v 1.65 2002/07/01 15:27:49 tgl Exp $
* $Id: view.c,v 1.66 2002/07/12 18:43:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/xact.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/namespace.h"
#include "commands/tablecmds.h"
......@@ -252,16 +253,21 @@ DefineView(const RangeVar *view, Query *viewParse)
* RemoveView
*
* Remove a view given its name
*
* We just have to drop the relation; the associated rules will be
* cleaned up automatically.
*/
void
RemoveView(const RangeVar *view, DropBehavior behavior)
{
Oid viewOid;
ObjectAddress object;
viewOid = RangeVarGetRelid(view, false);
/*
* We just have to drop the relation; the associated rules will be
* cleaned up automatically.
*/
heap_drop_with_catalog(viewOid, allowSystemTableMods);
object.classId = RelOid_pg_class;
object.objectId = viewOid;
object.objectSubId = 0;
performDeletion(&object, behavior);
}
......@@ -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.192 2002/07/01 15:27:51 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.193 2002/07/12 18:43:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1505,11 +1505,12 @@ _copyFkConstraint(FkConstraint *from)
Node_Copy(from, newnode, pktable);
Node_Copy(from, newnode, fk_attrs);
Node_Copy(from, newnode, pk_attrs);
if (from->match_type)
newnode->match_type = pstrdup(from->match_type);
newnode->actions = from->actions;
newnode->fk_matchtype = from->fk_matchtype;
newnode->fk_upd_action = from->fk_upd_action;
newnode->fk_del_action = from->fk_del_action;
newnode->deferrable = from->deferrable;
newnode->initdeferred = from->initdeferred;
newnode->skip_validation = from->skip_validation;
return newnode;
}
......@@ -2089,6 +2090,7 @@ _copyIndexStmt(IndexStmt *from)
Node_Copy(from, newnode, rangetable);
newnode->unique = from->unique;
newnode->primary = from->primary;
newnode->isconstraint = from->isconstraint;
return newnode;
}
......
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.
......@@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2002, 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.156 2002/06/20 20:29:41 momjian Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.157 2002/07/12 18:43:18 tgl Exp $
#
#-------------------------------------------------------------------------
......@@ -682,11 +682,11 @@ $ECHO_N "enabling unlimited row size for system tables... "$ECHO_C
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
ALTER TABLE pg_attrdef CREATE TOAST TABLE;
ALTER TABLE pg_constraint CREATE TOAST TABLE;
ALTER TABLE pg_database CREATE TOAST TABLE;
ALTER TABLE pg_description CREATE TOAST TABLE;
ALTER TABLE pg_group CREATE TOAST TABLE;
ALTER TABLE pg_proc CREATE TOAST TABLE;
ALTER TABLE pg_relcheck CREATE TOAST TABLE;
ALTER TABLE pg_rewrite CREATE TOAST TABLE;
ALTER TABLE pg_shadow CREATE TOAST TABLE;
ALTER TABLE pg_statistic CREATE TOAST TABLE;
......
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.
......@@ -27,7 +27,7 @@
extern void CommentObject(CommentStmt *stmt);
extern void DeleteComments(Oid oid, Oid classoid);
extern void DeleteComments(Oid oid, Oid classoid, int32 subid);
extern void CreateComments(Oid oid, Oid classoid, int32 subid, char *comment);
......
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