út 14. 7. 2020 v 15:55 odesílatel David G. Johnston < david.g.johns...@gmail.com> napsal:
> On Tue, Jul 14, 2020 at 5:40 AM Justin Pryzby <pry...@telsasoft.com> > wrote: > >> On Tue, Jul 14, 2020 at 07:25:56AM +0200, Pavel Stehule wrote: >> > út 14. 7. 2020 v 0:37 odesílatel David G. Johnston < >> david.g.johns...@gmail.com> napsal: >> > > On Mon, Jul 13, 2020 at 2:12 AM Pavel Stehule < >> pavel.steh...@gmail.com> wrote: >> > I think so now all changes are correct and valuable. I''l mark this >> patch >> > as ready for commit >> >> This is failing relevant tests in cfbot: >> >> drop_if_exists ... FAILED 450 ms >> >> > Oops, did a minor whitespace cleanup in the test file and didn't re-copy > expected output. I'm actually going to try and clean up the commenting in > the test file a bit to make it easier to read, and split out the glossary > changes into their own diff so that the bulk of the changes can be > back-patched. > > Further comments welcome so I'm putting it back into needs review for the > moment while I work on the refactor. > attached fixed patch all tests passed doc build without problems > David J. >
diff --git a/doc/src/sgml/glossary.sgml b/doc/src/sgml/glossary.sgml index 76525c6302..1dac096f23 100644 --- a/doc/src/sgml/glossary.sgml +++ b/doc/src/sgml/glossary.sgml @@ -1689,6 +1689,30 @@ </glossdef> </glossentry> + <glossentry id="glossary-type"> + <glossterm>Type</glossterm> + <glossdef> + <para> + All data stored within the database is typed. Each type has both a name, and associated + properties, as well as an overarching Type, of which there are two variations. Extensible + types can created by users and comprise of: base, composite, domain, enum, and range. There + are also the system-only pseudo-types. Type records are stored in pg_type and the + overarching type is found in pg_type.typtype. + </para> + </glossdef> + </glossentry> + + <glossentry id="glossary-type-definition"> + <glossterm>Type Definition</glossterm> + <glossdef> + <para> + Collective term for the various <glossterm linkend="glossary-type">Type</glossterm> + variants that are allowed for pg_type.typtype catalog table column values; + specifically, ones that are extensible. + </para> + </glossdef> + </glossentry> + <glossentry id="glossary-unique-constraint"> <glossterm>Unique constraint</glossterm> <glossdef> diff --git a/doc/src/sgml/ref/drop_domain.sgml b/doc/src/sgml/ref/drop_domain.sgml index b18faf3917..8b04b3818b 100644 --- a/doc/src/sgml/ref/drop_domain.sgml +++ b/doc/src/sgml/ref/drop_domain.sgml @@ -30,7 +30,9 @@ DROP DOMAIN [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, . <para> <command>DROP DOMAIN</command> removes a domain. Only the owner of - a domain can remove it. + a domain can remove it. The duplicates the functionality provided by + <xref linkend="sql-droptype"/> but restricts the object type to domain. + </para> </refsect1> @@ -42,8 +44,13 @@ DROP DOMAIN [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, . <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the domain does not exist. A notice is issued - in this case. + This parameter instructs <productname>PostgreSQL</productname> to search + for the first instance of any + <glossterm linkend="glossary-type-definition">type definition</glossterm> + with the provided name. + If no type definitions are found a notice is issued and the command ends. + If a type definition is found then one of two things will happen: + if the type definition is a domain it is dropped, otherwise the command fails. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_foreign_table.sgml b/doc/src/sgml/ref/drop_foreign_table.sgml index 07b3fd4251..0288fb2062 100644 --- a/doc/src/sgml/ref/drop_foreign_table.sgml +++ b/doc/src/sgml/ref/drop_foreign_table.sgml @@ -42,8 +42,11 @@ DROP FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceabl <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the foreign table does not exist. - A notice is issued in this case. + This parameter instructs <productname>PostgreSQL</productname> to search + for the first instance of any relation with the provided name. + If no relations are found a notice is issued and the command ends. + If a relation is found then one of two things will happen: + if the relation is a foreign table it is dropped, otherwise the command fails. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_index.sgml b/doc/src/sgml/ref/drop_index.sgml index 0aedd71bd6..dff437cf9b 100644 --- a/doc/src/sgml/ref/drop_index.sgml +++ b/doc/src/sgml/ref/drop_index.sgml @@ -70,8 +70,11 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] <replaceable class="parameter">name</r <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the index does not exist. A notice is issued - in this case. + This parameter instructs <productname>PostgreSQL</productname> to search + for the first instance of any relation with the provided name. + If no relations are found a notice is issued and the command ends. + If a relation is found then one of two things will happen: + if the relation is an index it is dropped, otherwise the command fails. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_materialized_view.sgml b/doc/src/sgml/ref/drop_materialized_view.sgml index c8f3bc5b0d..6647a0db0d 100644 --- a/doc/src/sgml/ref/drop_materialized_view.sgml +++ b/doc/src/sgml/ref/drop_materialized_view.sgml @@ -43,8 +43,11 @@ DROP MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</replac <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the materialized view does not exist. A notice - is issued in this case. + This parameter instructs <productname>PostgreSQL</productname> to search + for the first instance of any relation with the provided name. + If no relations are found a notice is issued and the command ends. + If a relation is found then one of two things will happen: + if the relation is a materialized view it is dropped, otherwise the command fails. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_sequence.sgml b/doc/src/sgml/ref/drop_sequence.sgml index 387c98edbc..b3209d6d01 100644 --- a/doc/src/sgml/ref/drop_sequence.sgml +++ b/doc/src/sgml/ref/drop_sequence.sgml @@ -42,8 +42,11 @@ DROP SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the sequence does not exist. A notice is issued - in this case. + This parameter instructs <productname>PostgreSQL</productname> to search + for the first instance of any relation with the provided name. + If no relations are found a notice is issued and the command ends. + If a relation is found then one of two things will happen: + if the relation is a sequence it is dropped, otherwise the command fails. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_table.sgml b/doc/src/sgml/ref/drop_table.sgml index bf8996d198..9c9147f2ef 100644 --- a/doc/src/sgml/ref/drop_table.sgml +++ b/doc/src/sgml/ref/drop_table.sgml @@ -55,8 +55,11 @@ DROP TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, .. <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the table does not exist. A notice is issued - in this case. + This parameter instructs <productname>PostgreSQL</productname> to search + for the first instance of any relation with the provided name. + If no relations are found a notice is issued and the command ends. + If a relation is found then one of two things will happen: + if the relation is a table it is dropped, otherwise the command fails. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_type.sgml b/doc/src/sgml/ref/drop_type.sgml index 9e555c0624..305a62486f 100644 --- a/doc/src/sgml/ref/drop_type.sgml +++ b/doc/src/sgml/ref/drop_type.sgml @@ -42,8 +42,17 @@ DROP TYPE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ... <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the type does not exist. A notice is issued - in this case. + This parameter instructs <productname>PostgreSQL</productname> to search + for the first instance of any + <glossterm linkend="glossary-type-definition">type definition</glossterm> + with the provided name. + If no type definitions are found a notice is issued and the command ends. + If a type definition is found then it will be dropped. This includes + domains even though they have their own drop command. + + However, an attempt to drop the automatically created composite type of an + existing relation will fail as the relation has a dependency on the found + type definition. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_view.sgml b/doc/src/sgml/ref/drop_view.sgml index a1c550ec3e..ff75410cf1 100644 --- a/doc/src/sgml/ref/drop_view.sgml +++ b/doc/src/sgml/ref/drop_view.sgml @@ -42,8 +42,11 @@ DROP VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ... <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the view does not exist. A notice is issued - in this case. + This parameter instructs <productname>PostgreSQL</productname> to search + for the first instance of any relation with the provided name. + If no relations are found a notice is issued and the command ends. + If a relation is found then one of two things will happen: + if the relation is a view it is dropped, otherwise the command fails. </para> </listitem> </varlistentry> diff --git a/src/test/regress/expected/drop_if_exists.out b/src/test/regress/expected/drop_if_exists.out index 5e44c2c3ce..f328d94b9e 100644 --- a/src/test/regress/expected/drop_if_exists.out +++ b/src/test/regress/expected/drop_if_exists.out @@ -330,6 +330,167 @@ HINT: Specify the argument list to select the routine unambiguously. -- cleanup DROP PROCEDURE test_ambiguous_procname(int); DROP PROCEDURE test_ambiguous_procname(text); +-- Demonstrate namespace collision behavior +CREATE SCHEMA test_if_exists_first; +CREATE SCHEMA test_if_exists_second; +SET search_path TO test_if_exists_first, test_if_exists_second; +DROP TABLE test_if_exists_second.test_rel_exists; +ERROR: table "test_rel_exists" does not exist +DROP TABLE IF EXISTS test_if_exists_second.test_rel_exists; +NOTICE: table "test_rel_exists" does not exist, skipping +CREATE TABLE test_if_exists_second.test_rel_exists (a int, b text); +CREATE TABLE test_if_exists_first.test_rel_with_index (ai int, bi text); +-- table presence in the second schema causes a failure here +-- even though a corresponding non-schema-qualified create +-- statement would succeed. +DROP VIEW IF EXISTS test_rel_exists; +ERROR: "test_rel_exists" is not a view +HINT: Use DROP TABLE to remove a table. +DROP INDEX IF EXISTS test_rel_exists; +ERROR: "test_rel_exists" is not an index +HINT: Use DROP TABLE to remove a table. +DROP TYPE IF EXISTS test_rel_exists; +ERROR: cannot drop type test_rel_exists because table test_rel_exists requires it +HINT: You can drop table test_rel_exists instead. +DROP SEQUENCE IF EXISTS test_rel_exists; +ERROR: "test_rel_exists" is not a sequence +HINT: Use DROP TABLE to remove a table. +DROP MATERIALIZED VIEW IF EXISTS test_rel_exists; +ERROR: "test_rel_exists" is not a materialized view +HINT: Use DROP TABLE to remove a table. +DROP FOREIGN TABLE IF EXISTS test_rel_exists; +ERROR: "test_rel_exists" is not a foreign table +HINT: Use DROP TABLE to remove a table. +-- a role is not a relation so this shouldn't be affected +DROP ROLE IF EXISTS test_rel_exists; +NOTICE: role "test_rel_exists" does not exist, skipping +-- type affirmation (this isn't the same as the implicit type created with the table) +CREATE TYPE test_if_exists_first.test_rel_exists AS (c text, d int); +-- existence of type prevents finding the table +DROP TABLE test_rel_exists; +ERROR: "test_rel_exists" is not a table +HINT: Use DROP TYPE to remove a type. +-- cleanup +DROP TYPE IF EXISTS test_rel_exists; +-- view affirmation +CREATE VIEW test_if_exists_first.test_rel_exists AS + SELECT 1::bigint AS d, 'e'::text AS e; +-- existence of view prevents finding the table +DROP TABLE test_rel_exists; +ERROR: "test_rel_exists" is not a table +HINT: Use DROP VIEW to remove a view. +-- cleanup +DROP VIEW test_rel_exists; +-- index affirmation +CREATE INDEX test_rel_exists ON test_if_exists_first.test_rel_with_index (ai); +-- existence of index prevents finding the table +DROP TABLE test_rel_exists; +ERROR: "test_rel_exists" is not a table +HINT: Use DROP INDEX to remove an index. +-- cleanup +DROP INDEX test_rel_exists; +-- sequence affirmation +CREATE SEQUENCE test_rel_exists; +-- existence of sequence prevents finding the table +DROP TABLE test_rel_exists; +ERROR: "test_rel_exists" is not a table +HINT: Use DROP SEQUENCE to remove a sequence. +-- cleanup +DROP SEQUENCE test_rel_exists; +-- materialized affirmation +CREATE MATERIALIZED VIEW test_if_exists_first.test_rel_exists AS + SELECT 1::bigint AS d, 'e'::text AS e; +-- existence of materialized view prevents finding the table +DROP TABLE test_rel_exists; +ERROR: "test_rel_exists" is not a table +HINT: Use DROP MATERIALIZED VIEW to remove a materialized view. +-- schema qualification works though (and cleanup) +DROP TABLE test_if_exists_second.test_rel_exists; +DROP MATERIALIZED VIEW test_rel_exists; +DROP TABLE test_if_exists_first.test_rel_with_index; +-- Type & Domain behavior is thus: +CREATE TABLE test_if_exists_second.test_rel_exists (a int, b text); +-- domain dropping errors with presence of table; no hint provided +DROP DOMAIN IF EXISTS test_rel_exists; +ERROR: "test_rel_exists" is not a domain +-- domain affirmation +CREATE DOMAIN test_rel_exists int4; +-- existence of domain in first search_path schema +-- does not prevent second search_path table dropping +DROP TABLE test_rel_exists; +-- cleanup +DROP DOMAIN test_rel_exists; +-- setup +CREATE TABLE test_if_exists_second.test_rel_exists (a int, b text); +-- type with same name exists as table creation creates a composite type +CREATE TYPE test_if_exists_second.test_rel_exists AS (c int, d text); +ERROR: type "test_rel_exists" already exists +-- domain creation with same name as table fails as auto-generated type conflicts +CREATE DOMAIN test_if_exists_second.test_rel_exists int4; +ERROR: type "test_rel_exists" already exists +-- cannot independently drop a composite type associated with a table +DROP TYPE IF EXISTS test_if_exists_second.test_rel_exists; +ERROR: cannot drop type test_rel_exists because table test_rel_exists requires it +HINT: You can drop table test_rel_exists instead. +-- cleanup +DROP TABLE test_if_exists_second.test_rel_exists; +-- setup +CREATE TYPE test_if_exists_second.test_rel_exists AS (c int, d text); +-- auto-created type (which is added also as a relation) prevents table from being created +CREATE TABLE test_if_exists_second.test_rel_exists (a int, b text); +ERROR: relation "test_rel_exists" already exists +-- a composite type is not a domain so a conditional drop fails +DROP DOMAIN IF EXISTS test_if_exists_second.test_rel_exists; +ERROR: "test_if_exists_second.test_rel_exists" is not a domain +-- can still create a domain in the first schema +CREATE DOMAIN test_rel_exists int4; +-- unlike the case with relations the fact that domains +-- and other extensible types share the same namespace +-- doesn't cause a DROP TYPE command that first +-- finds a domain to fail - though it does prevent +-- the search algorithm from looking in the second +-- schema for an exact match. +DROP TYPE IF EXISTS test_rel_exists; -- This removes the domain + -- type present, not a domain +DROP DOMAIN IF EXISTS test_if_exists_second.test_rel_exists; +ERROR: "test_if_exists_second.test_rel_exists" is not a domain +-- Yep, domain seems to have been removed +DROP TYPE IF EXISTS test_if_exists_first.test_rel_exists; +NOTICE: type "test_if_exists_first.test_rel_exists" does not exist, skipping +-- Yep, domain removed, finding the type +DROP DOMAIN test_rel_exists; +ERROR: "test_rel_exists" is not a domain +-- cleanup +DROP TYPE test_rel_exists; +-- test with domain second and type first +CREATE TYPE test_if_exists_first.test_rel_exists AS (c int, d text); +CREATE DOMAIN test_if_exists_second.test_rel_exists int4; +-- fails since the first matched name is not a domain +DROP DOMAIN IF EXISTS test_rel_exists; +ERROR: "test_rel_exists" is not a domain +-- remove the matching type +DROP TYPE IF EXISTS test_rel_exists; +-- drop type cleans up domains... +DROP TYPE IF EXISTS test_if_exists_second.test_rel_exists; +-- ...so it no longer exists here +DROP DOMAIN IF EXISTS test_rel_exists; +NOTICE: type "test_rel_exists" does not exist, skipping +-- /Type & Domain +-- Bug # 16492 - this script produces an error, arguably it should not +CREATE TABLE test_if_exists_first.test_rel_exists (a int, b text); +DROP TABLE IF EXISTS test_if_exists_first.test_rel_exists; +DROP VIEW IF EXISTS test_if_exists_first.test_rel_exists; +NOTICE: view "test_rel_exists" does not exist, skipping +CREATE VIEW test_if_exists_first.test_rel_exists AS + SELECT 1::int AS a, 'one'::text AS b; +DROP TABLE IF EXISTS test_if_exists_first.test_rel_exists; +ERROR: "test_rel_exists" is not a table +HINT: Use DROP VIEW to remove a view. +DROP VIEW IF EXISTS test_if_exists_first.test_rel_exists; +CREATE VIEW test_if_exists_first.test_rel_exists AS + SELECT 1::int AS a, 'one'::text AS b; +DROP VIEW test_if_exists_first.test_rel_exists; +-- /Bug # 16492 -- This test checks both the functionality of 'if exists' and the syntax -- of the drop database command. drop database test_database_exists (force); diff --git a/src/test/regress/sql/drop_if_exists.sql b/src/test/regress/sql/drop_if_exists.sql index ac6168b91f..5cb7f17875 100644 --- a/src/test/regress/sql/drop_if_exists.sql +++ b/src/test/regress/sql/drop_if_exists.sql @@ -296,6 +296,142 @@ DROP ROUTINE IF EXISTS test_ambiguous_procname; DROP PROCEDURE test_ambiguous_procname(int); DROP PROCEDURE test_ambiguous_procname(text); +-- Demonstrate namespace collision behavior +CREATE SCHEMA test_if_exists_first; +CREATE SCHEMA test_if_exists_second; +SET search_path TO test_if_exists_first, test_if_exists_second; + +DROP TABLE test_if_exists_second.test_rel_exists; +DROP TABLE IF EXISTS test_if_exists_second.test_rel_exists; +CREATE TABLE test_if_exists_second.test_rel_exists (a int, b text); +CREATE TABLE test_if_exists_first.test_rel_with_index (ai int, bi text); + +-- table presence in the second schema causes a failure here +-- even though a corresponding non-schema-qualified create +-- statement would succeed. +DROP VIEW IF EXISTS test_rel_exists; +DROP INDEX IF EXISTS test_rel_exists; +DROP TYPE IF EXISTS test_rel_exists; +DROP SEQUENCE IF EXISTS test_rel_exists; +DROP MATERIALIZED VIEW IF EXISTS test_rel_exists; +DROP FOREIGN TABLE IF EXISTS test_rel_exists; + +-- a role is not a relation so this shouldn't be affected +DROP ROLE IF EXISTS test_rel_exists; + +-- type affirmation (this isn't the same as the implicit type created with the table) +CREATE TYPE test_if_exists_first.test_rel_exists AS (c text, d int); +-- existence of type prevents finding the table +DROP TABLE test_rel_exists; +-- cleanup +DROP TYPE IF EXISTS test_rel_exists; + +-- view affirmation +CREATE VIEW test_if_exists_first.test_rel_exists AS + SELECT 1::bigint AS d, 'e'::text AS e; +-- existence of view prevents finding the table +DROP TABLE test_rel_exists; +-- cleanup +DROP VIEW test_rel_exists; + +-- index affirmation +CREATE INDEX test_rel_exists ON test_if_exists_first.test_rel_with_index (ai); +-- existence of index prevents finding the table +DROP TABLE test_rel_exists; +-- cleanup +DROP INDEX test_rel_exists; + +-- sequence affirmation +CREATE SEQUENCE test_rel_exists; +-- existence of sequence prevents finding the table +DROP TABLE test_rel_exists; +-- cleanup +DROP SEQUENCE test_rel_exists; + +-- materialized affirmation +CREATE MATERIALIZED VIEW test_if_exists_first.test_rel_exists AS + SELECT 1::bigint AS d, 'e'::text AS e; +-- existence of materialized view prevents finding the table +DROP TABLE test_rel_exists; + +-- schema qualification works though (and cleanup) +DROP TABLE test_if_exists_second.test_rel_exists; +DROP MATERIALIZED VIEW test_rel_exists; +DROP TABLE test_if_exists_first.test_rel_with_index; + +-- Type & Domain behavior is thus: +CREATE TABLE test_if_exists_second.test_rel_exists (a int, b text); +-- domain dropping errors with presence of table; no hint provided +DROP DOMAIN IF EXISTS test_rel_exists; +-- domain affirmation +CREATE DOMAIN test_rel_exists int4; +-- existence of domain in first search_path schema +-- does not prevent second search_path table dropping +DROP TABLE test_rel_exists; +-- cleanup +DROP DOMAIN test_rel_exists; + +-- setup +CREATE TABLE test_if_exists_second.test_rel_exists (a int, b text); +-- type with same name exists as table creation creates a composite type +CREATE TYPE test_if_exists_second.test_rel_exists AS (c int, d text); +-- domain creation with same name as table fails as auto-generated type conflicts +CREATE DOMAIN test_if_exists_second.test_rel_exists int4; +-- cannot independently drop a composite type associated with a table +DROP TYPE IF EXISTS test_if_exists_second.test_rel_exists; +-- cleanup +DROP TABLE test_if_exists_second.test_rel_exists; + +-- setup +CREATE TYPE test_if_exists_second.test_rel_exists AS (c int, d text); +-- auto-created type (which is added also as a relation) prevents table from being created +CREATE TABLE test_if_exists_second.test_rel_exists (a int, b text); +-- a composite type is not a domain so a conditional drop fails +DROP DOMAIN IF EXISTS test_if_exists_second.test_rel_exists; +-- can still create a domain in the first schema +CREATE DOMAIN test_rel_exists int4; +-- unlike the case with relations the fact that domains +-- and other extensible types share the same namespace +-- doesn't cause a DROP TYPE command that first +-- finds a domain to fail - though it does prevent +-- the search algorithm from looking in the second +-- schema for an exact match. +DROP TYPE IF EXISTS test_rel_exists; -- This removes the domain + -- type present, not a domain +DROP DOMAIN IF EXISTS test_if_exists_second.test_rel_exists; +-- Yep, domain seems to have been removed +DROP TYPE IF EXISTS test_if_exists_first.test_rel_exists; +-- Yep, domain removed, finding the type +DROP DOMAIN test_rel_exists; +-- cleanup +DROP TYPE test_rel_exists; + +-- test with domain second and type first +CREATE TYPE test_if_exists_first.test_rel_exists AS (c int, d text); +CREATE DOMAIN test_if_exists_second.test_rel_exists int4; +-- fails since the first matched name is not a domain +DROP DOMAIN IF EXISTS test_rel_exists; +-- remove the matching type +DROP TYPE IF EXISTS test_rel_exists; +-- drop type cleans up domains... +DROP TYPE IF EXISTS test_if_exists_second.test_rel_exists; +-- ...so it no longer exists here +DROP DOMAIN IF EXISTS test_rel_exists; +-- /Type & Domain + +-- Bug # 16492 - this script produces an error, arguably it should not +CREATE TABLE test_if_exists_first.test_rel_exists (a int, b text); +DROP TABLE IF EXISTS test_if_exists_first.test_rel_exists; +DROP VIEW IF EXISTS test_if_exists_first.test_rel_exists; +CREATE VIEW test_if_exists_first.test_rel_exists AS + SELECT 1::int AS a, 'one'::text AS b; +DROP TABLE IF EXISTS test_if_exists_first.test_rel_exists; +DROP VIEW IF EXISTS test_if_exists_first.test_rel_exists; +CREATE VIEW test_if_exists_first.test_rel_exists AS + SELECT 1::int AS a, 'one'::text AS b; +DROP VIEW test_if_exists_first.test_rel_exists; +-- /Bug # 16492 + -- This test checks both the functionality of 'if exists' and the syntax -- of the drop database command. drop database test_database_exists (force);