drop if exists - first piece - Mailing list pgsql-patches

From Andrew Dunstan
Subject drop if exists - first piece
Date
Msg-id 437E58DC.2090700@dunslane.net
Whole thread Raw
Responses Re: drop if exists - first piece
List pgsql-patches
I will apply the attached patch tomorrow, barring objection. This covers
drop if exists for the following objects:

  table view index sequence schema type domain conversion

I have a simple test script as show below, but I am not sure where to
put it in the regression tests - add a new one maybe? The test for each
object proves that the object doesn't exist, shows that we don't
generate an error using IF EXISTS when it doesn't exist, and then shows
that we do drop the object properly if it does exist.

cheers

andrew

--
-- IF EXISTS tests
--

-- table (will be really dropped at the end)

DROP TABLE test_exists;

DROP TABLE IF EXISTS test_exists;

CREATE TABLE test_exists (a int, b text);

-- view

DROP VIEW test_view_exists;

DROP VIEW IF EXISTS test_view_exists;

CREATE VIEW test_view_exists AS select * from test_exists;

DROP VIEW IF EXISTS test_view_exists;

DROP VIEW test_view_exists;

-- index

DROP INDEX test_index_exists;

DROP INDEX IF EXISTS test_index_exists;

CREAT INDEX test_index_exists on test_view_exists(a);

DROP INDEX IF EXISTS test_index_exists;

DROP INDEX test_index_exists;

-- sequence

DROP SEQUENCE test_sequence_exists;

DROP SEQUENCE IF EXISTS test_sequence_exists;

CREATE SEQUENCE test_sequence_exists;

DROP SEQUENCE IF EXISTS test_sequence_exists;

DROP SEQUENCE test_sequence_exists;

-- schema

DROP SCHEMA test_schema_exists;

DROP SCHEMA IF EXISTS test_schema_exists;

CREATE SCHEMA test_schema_exists;

DROP SCHEMA IF EXISTS test_schema_exists;

DROP SCHEMA test_schema_exists;

-- type

DROP TYPE test_type_exists;

DROP TYPE IF EXISTS test__type_exists;

CREATE type test_type_exists as (a int, b text);

DROP TYPE IF EXISTS test__type_exists;

DROP TYPE test_type_exists;

-- domain

DROP DOMAIN test_domain_exists;

DROP DOMAIN IF EXISTS test__domain_exists;

CREATE domain test_domain_exists as int not null check (value > 0);

DROP DOMAIN IF EXISTS test__domain_exists;

DROP DOMAIN test_domain_exists;

-- drop the table


DROP TABLE IF EXISTS test_exists;

DROP TABLE test_exists;




Index: src/backend/commands/conversioncmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v
retrieving revision 1.23
diff -c -r1.23 conversioncmds.c
*** src/backend/commands/conversioncmds.c    15 Oct 2005 02:49:15 -0000    1.23
--- src/backend/commands/conversioncmds.c    18 Nov 2005 20:39:44 -0000
***************
*** 98,113 ****
   * DROP CONVERSION
   */
  void
! DropConversionCommand(List *name, DropBehavior behavior)
  {
      Oid            conversionOid;

      conversionOid = FindConversionByName(name);
      if (!OidIsValid(conversionOid))
!         ereport(ERROR,
!                 (errcode(ERRCODE_UNDEFINED_OBJECT),
!                  errmsg("conversion \"%s\" does not exist",
!                         NameListToString(name))));

      ConversionDrop(conversionOid, behavior);
  }
--- 98,128 ----
   * DROP CONVERSION
   */
  void
! DropConversionCommand(List *name, DropBehavior behavior, bool missing_ok)
  {
      Oid            conversionOid;

      conversionOid = FindConversionByName(name);
      if (!OidIsValid(conversionOid))
!     {
!         if (! missing_ok)
!         {
!             ereport(ERROR,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("conversion \"%s\" does not exist",
!                             NameListToString(name))));
!         }
!         else
!         {
!             ereport(NOTICE,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("conversion \"%s\" does not exist, skipping",
!                             NameListToString(name))));
!         }
!
!         Assert(missing_ok);
!         return;
!     }

      ConversionDrop(conversionOid, behavior);
  }
Index: src/backend/commands/schemacmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v
retrieving revision 1.35
diff -c -r1.35 schemacmds.c
*** src/backend/commands/schemacmds.c    15 Oct 2005 02:49:15 -0000    1.35
--- src/backend/commands/schemacmds.c    18 Nov 2005 20:39:44 -0000
***************
*** 147,153 ****
   *        Removes a schema.
   */
  void
! RemoveSchema(List *names, DropBehavior behavior)
  {
      char       *namespaceName;
      Oid            namespaceId;
--- 147,153 ----
   *        Removes a schema.
   */
  void
! RemoveSchema(List *names, DropBehavior behavior, bool missing_ok)
  {
      char       *namespaceName;
      Oid            namespaceId;
***************
*** 163,171 ****
                                   CStringGetDatum(namespaceName),
                                   0, 0, 0);
      if (!OidIsValid(namespaceId))
!         ereport(ERROR,
!                 (errcode(ERRCODE_UNDEFINED_SCHEMA),
!                  errmsg("schema \"%s\" does not exist", namespaceName)));

      /* Permission check */
      if (!pg_namespace_ownercheck(namespaceId, GetUserId()))
--- 163,186 ----
                                   CStringGetDatum(namespaceName),
                                   0, 0, 0);
      if (!OidIsValid(namespaceId))
!     {
!         if (!missing_ok)
!         {
!             ereport(ERROR,
!                     (errcode(ERRCODE_UNDEFINED_SCHEMA),
!                      errmsg("schema \"%s\" does not exist", namespaceName)));
!         }
!         else
!         {
!             ereport(NOTICE,
!                     (errcode(ERRCODE_UNDEFINED_SCHEMA),
!                      errmsg("schema \"%s\" does not exist, skipping",
!                             namespaceName)));
!         }
!
!         Assert(missing_ok);
!         return;
!     }

      /* Permission check */
      if (!pg_namespace_ownercheck(namespaceId, GetUserId()))
Index: src/backend/commands/typecmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/typecmds.c,v
retrieving revision 1.82
diff -c -r1.82 typecmds.c
*** src/backend/commands/typecmds.c    18 Oct 2005 01:06:24 -0000    1.82
--- src/backend/commands/typecmds.c    18 Nov 2005 20:39:46 -0000
***************
*** 398,404 ****
   *        Removes a datatype.
   */
  void
! RemoveType(List *names, DropBehavior behavior)
  {
      TypeName   *typename;
      Oid            typeoid;
--- 398,404 ----
   *        Removes a datatype.
   */
  void
! RemoveType(List *names, DropBehavior behavior, bool missing_ok)
  {
      TypeName   *typename;
      Oid            typeoid;
***************
*** 414,423 ****
      /* Use LookupTypeName here so that shell types can be removed. */
      typeoid = LookupTypeName(typename);
      if (!OidIsValid(typeoid))
!         ereport(ERROR,
!                 (errcode(ERRCODE_UNDEFINED_OBJECT),
!                  errmsg("type \"%s\" does not exist",
!                         TypeNameToString(typename))));

      tup = SearchSysCache(TYPEOID,
                           ObjectIdGetDatum(typeoid),
--- 414,438 ----
      /* Use LookupTypeName here so that shell types can be removed. */
      typeoid = LookupTypeName(typename);
      if (!OidIsValid(typeoid))
!     {
!         if (!missing_ok)
!         {
!             ereport(ERROR,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("type \"%s\" does not exist",
!                             TypeNameToString(typename))));
!         }
!         else
!         {
!             ereport(NOTICE,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("type \"%s\" does not exist, skipping",
!                             TypeNameToString(typename))));
!         }
!
!         Assert(missing_ok);
!         return;
!     }

      tup = SearchSysCache(TYPEOID,
                           ObjectIdGetDatum(typeoid),
***************
*** 779,785 ****
   * This is identical to RemoveType except we insist it be a domain.
   */
  void
! RemoveDomain(List *names, DropBehavior behavior)
  {
      TypeName   *typename;
      Oid            typeoid;
--- 794,800 ----
   * This is identical to RemoveType except we insist it be a domain.
   */
  void
! RemoveDomain(List *names, DropBehavior behavior, bool missing_ok)
  {
      TypeName   *typename;
      Oid            typeoid;
***************
*** 796,805 ****
      /* Use LookupTypeName here so that shell types can be removed. */
      typeoid = LookupTypeName(typename);
      if (!OidIsValid(typeoid))
!         ereport(ERROR,
!                 (errcode(ERRCODE_UNDEFINED_OBJECT),
!                  errmsg("type \"%s\" does not exist",
!                         TypeNameToString(typename))));

      tup = SearchSysCache(TYPEOID,
                           ObjectIdGetDatum(typeoid),
--- 811,835 ----
      /* Use LookupTypeName here so that shell types can be removed. */
      typeoid = LookupTypeName(typename);
      if (!OidIsValid(typeoid))
!     {
!         if (!missing_ok)
!         {
!             ereport(ERROR,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("type \"%s\" does not exist",
!                             TypeNameToString(typename))));
!         }
!         else
!         {
!             ereport(NOTICE,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("type \"%s\" does not exist, skipping",
!                             TypeNameToString(typename))));
!         }
!
!         Assert(missing_ok);
!         return;
!     }

      tup = SearchSysCache(TYPEOID,
                           ObjectIdGetDatum(typeoid),
Index: src/backend/parser/gram.y
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.512
diff -c -r2.512 gram.y
*** src/backend/parser/gram.y    13 Nov 2005 19:11:28 -0000    2.512
--- src/backend/parser/gram.y    18 Nov 2005 20:39:53 -0000
***************
*** 173,179 ****
  %type <ival>    opt_lock lock_type cast_context
  %type <boolean>    opt_force opt_or_replace
                  opt_grant_grant_option opt_grant_admin_option
!                 opt_nowait

  %type <boolean>    like_including_defaults

--- 173,179 ----
  %type <ival>    opt_lock lock_type cast_context
  %type <boolean>    opt_force opt_or_replace
                  opt_grant_grant_option opt_grant_admin_option
!                 opt_nowait

  %type <boolean>    like_including_defaults

***************
*** 362,368 ****

      HANDLER HAVING HEADER HOLD HOUR_P

!     ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
      INDEX INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
      INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
      INTERVAL INTO INVOKER IS ISNULL ISOLATION
--- 362,368 ----

      HANDLER HAVING HEADER HOLD HOUR_P

!     IF ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
      INDEX INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
      INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
      INTERVAL INTO INVOKER IS ISNULL ISOLATION
***************
*** 2818,2837 ****
   *
   *        QUERY:
   *
!  *        DROP itemtype itemname [, itemname ...] [ RESTRICT | CASCADE ]
   *
   *****************************************************************************/

! DropStmt:    DROP drop_type any_name_list opt_drop_behavior
                  {
                      DropStmt *n = makeNode(DropStmt);
                      n->removeType = $2;
                      n->objects = $3;
                      n->behavior = $4;
                      $$ = (Node *)n;
                  }
          ;

  drop_type:    TABLE                                    { $$ = OBJECT_TABLE; }
              | SEQUENCE                                { $$ = OBJECT_SEQUENCE; }
              | VIEW                                    { $$ = OBJECT_VIEW; }
--- 2818,2849 ----
   *
   *        QUERY:
   *
!  *        DROP itemtype [ IF EXISTS ] itemname [, itemname ...]
!  *           [ RESTRICT | CASCADE ]
   *
   *****************************************************************************/

! DropStmt:    DROP drop_type IF EXISTS any_name_list opt_drop_behavior
                  {
                      DropStmt *n = makeNode(DropStmt);
                      n->removeType = $2;
+                     n->missing_ok = TRUE;
+                     n->objects = $5;
+                     n->behavior = $6;
+                     $$ = (Node *)n;
+                 }
+             | DROP drop_type any_name_list opt_drop_behavior
+                 {
+                     DropStmt *n = makeNode(DropStmt);
+                     n->removeType = $2;
+                     n->missing_ok = FALSE;
                      n->objects = $3;
                      n->behavior = $4;
                      $$ = (Node *)n;
                  }
          ;

+
  drop_type:    TABLE                                    { $$ = OBJECT_TABLE; }
              | SEQUENCE                                { $$ = OBJECT_SEQUENCE; }
              | VIEW                                    { $$ = OBJECT_VIEW; }
***************
*** 8159,8164 ****
--- 8171,8177 ----
              | HEADER
              | HOLD
              | HOUR_P
+             | IF
              | IMMEDIATE
              | IMMUTABLE
              | IMPLICIT_P
Index: src/backend/parser/keywords.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/keywords.c,v
retrieving revision 1.166
diff -c -r1.166 keywords.c
*** src/backend/parser/keywords.c    15 Oct 2005 02:49:22 -0000    1.166
--- src/backend/parser/keywords.c    18 Nov 2005 20:39:53 -0000
***************
*** 160,165 ****
--- 160,166 ----
      {"header", HEADER},
      {"hold", HOLD},
      {"hour", HOUR_P},
+     {"if",IF},
      {"ilike", ILIKE},
      {"immediate", IMMEDIATE},
      {"immutable", IMMUTABLE},
Index: src/backend/tcop/utility.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/tcop/utility.c,v
retrieving revision 1.245
diff -c -r1.245 utility.c
*** src/backend/tcop/utility.c    15 Oct 2005 02:49:27 -0000    1.245
--- src/backend/tcop/utility.c    18 Nov 2005 20:39:54 -0000
***************
*** 67,72 ****
--- 67,73 ----
      char        kind;
      int            nonexistent_code;
      const char *nonexistent_msg;
+     const char *skipping_msg;
      const char *nota_msg;
      const char *drophint_msg;
  };
***************
*** 75,100 ****
--- 76,106 ----
      {RELKIND_RELATION,
          ERRCODE_UNDEFINED_TABLE,
          gettext_noop("table \"%s\" does not exist"),
+         gettext_noop("table \"%s\" does not exist, skipping"),
          gettext_noop("\"%s\" is not a table"),
      gettext_noop("Use DROP TABLE to remove a table.")},
      {RELKIND_SEQUENCE,
          ERRCODE_UNDEFINED_TABLE,
          gettext_noop("sequence \"%s\" does not exist"),
+         gettext_noop("sequence \"%s\" does not exist, skipping"),
          gettext_noop("\"%s\" is not a sequence"),
      gettext_noop("Use DROP SEQUENCE to remove a sequence.")},
      {RELKIND_VIEW,
          ERRCODE_UNDEFINED_TABLE,
          gettext_noop("view \"%s\" does not exist"),
+         gettext_noop("view \"%s\" does not exist, skipping"),
          gettext_noop("\"%s\" is not a view"),
      gettext_noop("Use DROP VIEW to remove a view.")},
      {RELKIND_INDEX,
          ERRCODE_UNDEFINED_OBJECT,
          gettext_noop("index \"%s\" does not exist"),
+         gettext_noop("index \"%s\" does not exist, skipping"),
          gettext_noop("\"%s\" is not an index"),
      gettext_noop("Use DROP INDEX to remove an index.")},
      {RELKIND_COMPOSITE_TYPE,
          ERRCODE_UNDEFINED_OBJECT,
          gettext_noop("type \"%s\" does not exist"),
+         gettext_noop("type \"%s\" does not exist, skipping"),
          gettext_noop("\"%s\" is not a type"),
      gettext_noop("Use DROP TYPE to remove a type.")},
      {'\0', 0, NULL, NULL, NULL}
***************
*** 132,154 ****
   * non-existent relation
   */
  static void
! DropErrorMsgNonExistent(RangeVar *rel, char rightkind)
  {
      const struct msgstrings *rentry;

      for (rentry = msgstringarray; rentry->kind != '\0'; rentry++)
      {
          if (rentry->kind == rightkind)
!             ereport(ERROR,
!                     (errcode(rentry->nonexistent_code),
!                      errmsg(rentry->nonexistent_msg, rel->relname)));
      }

!     Assert(false);                /* Should be impossible */
  }

! static void
! CheckDropPermissions(RangeVar *rel, char rightkind)
  {
      Oid            relOid;
      HeapTuple    tuple;
--- 138,179 ----
   * non-existent relation
   */
  static void
! DropErrorMsgNonExistent(RangeVar *rel, char rightkind, bool missing_ok)
  {
      const struct msgstrings *rentry;

      for (rentry = msgstringarray; rentry->kind != '\0'; rentry++)
      {
          if (rentry->kind == rightkind)
!         {
!             if (! missing_ok)
!             {
!                 ereport(ERROR,
!                         (errcode(rentry->nonexistent_code),
!                          errmsg(rentry->nonexistent_msg, rel->relname)));
!             }
!             else
!             {
!                 ereport(NOTICE,
!                         (errcode(rentry->nonexistent_code),
!                          errmsg(rentry->skipping_msg, rel->relname)));
!                 break;
!             }
!         }
      }

!     Assert(missing_ok);       /* Should be impossible to get here otherwise */
  }

! /*
!  * returns false if missing_ok is true and the object does not exist,
!  * true if object exists and permissions are OK,
!  * errors otherwise
!  *
!  */
!
! static bool
! CheckDropPermissions(RangeVar *rel, char rightkind, bool missing_ok)
  {
      Oid            relOid;
      HeapTuple    tuple;
***************
*** 156,162 ****

      relOid = RangeVarGetRelid(rel, true);
      if (!OidIsValid(relOid))
!         DropErrorMsgNonExistent(rel, rightkind);

      tuple = SearchSysCache(RELOID,
                             ObjectIdGetDatum(relOid),
--- 181,192 ----

      relOid = RangeVarGetRelid(rel, true);
      if (!OidIsValid(relOid))
!     {
!         DropErrorMsgNonExistent(rel, rightkind, missing_ok);
!
!         Assert(missing_ok);
!         return false;
!     }

      tuple = SearchSysCache(RELOID,
                             ObjectIdGetDatum(relOid),
***************
*** 183,188 ****
--- 213,220 ----
                          rel->relname)));

      ReleaseSysCache(tuple);
+
+     return true;
  }

  /*
***************
*** 528,558 ****
                      {
                          case OBJECT_TABLE:
                              rel = makeRangeVarFromNameList(names);
!                             CheckDropPermissions(rel, RELKIND_RELATION);
!                             RemoveRelation(rel, stmt->behavior);
                              break;

                          case OBJECT_SEQUENCE:
                              rel = makeRangeVarFromNameList(names);
!                             CheckDropPermissions(rel, RELKIND_SEQUENCE);
!                             RemoveRelation(rel, stmt->behavior);
                              break;

                          case OBJECT_VIEW:
                              rel = makeRangeVarFromNameList(names);
!                             CheckDropPermissions(rel, RELKIND_VIEW);
!                             RemoveView(rel, stmt->behavior);
                              break;

                          case OBJECT_INDEX:
                              rel = makeRangeVarFromNameList(names);
!                             CheckDropPermissions(rel, RELKIND_INDEX);
!                             RemoveIndex(rel, stmt->behavior);
                              break;

                          case OBJECT_TYPE:
                              /* RemoveType does its own permissions checks */
!                             RemoveType(names, stmt->behavior);
                              break;

                          case OBJECT_DOMAIN:
--- 560,595 ----
                      {
                          case OBJECT_TABLE:
                              rel = makeRangeVarFromNameList(names);
!                             if (CheckDropPermissions(rel, RELKIND_RELATION,
!                                                      stmt->missing_ok))
!                                 RemoveRelation(rel, stmt->behavior);
                              break;

                          case OBJECT_SEQUENCE:
                              rel = makeRangeVarFromNameList(names);
!                             if (CheckDropPermissions(rel, RELKIND_SEQUENCE,
!                                                      stmt->missing_ok))
!                                 RemoveRelation(rel, stmt->behavior);
                              break;

                          case OBJECT_VIEW:
                              rel = makeRangeVarFromNameList(names);
!                             if (CheckDropPermissions(rel, RELKIND_VIEW,
!                                                      stmt->missing_ok))
!                                 RemoveView(rel, stmt->behavior);
                              break;

                          case OBJECT_INDEX:
                              rel = makeRangeVarFromNameList(names);
!                             if (CheckDropPermissions(rel, RELKIND_INDEX,
!                                                      stmt->missing_ok))
!                                 RemoveIndex(rel, stmt->behavior);
                              break;

                          case OBJECT_TYPE:
                              /* RemoveType does its own permissions checks */
!                             RemoveType(names, stmt->behavior,
!                                        stmt->missing_ok);
                              break;

                          case OBJECT_DOMAIN:
***************
*** 560,570 ****
                              /*
                               * RemoveDomain does its own permissions checks
                               */
!                             RemoveDomain(names, stmt->behavior);
                              break;

                          case OBJECT_CONVERSION:
!                             DropConversionCommand(names, stmt->behavior);
                              break;

                          case OBJECT_SCHEMA:
--- 597,609 ----
                              /*
                               * RemoveDomain does its own permissions checks
                               */
!                             RemoveDomain(names, stmt->behavior,
!                                          stmt->missing_ok);
                              break;

                          case OBJECT_CONVERSION:
!                             DropConversionCommand(names, stmt->behavior,
!                                                   stmt->missing_ok);
                              break;

                          case OBJECT_SCHEMA:
***************
*** 572,578 ****
                              /*
                               * RemoveSchema does its own permissions checks
                               */
!                             RemoveSchema(names, stmt->behavior);
                              break;

                          default:
--- 611,618 ----
                              /*
                               * RemoveSchema does its own permissions checks
                               */
!                             RemoveSchema(names, stmt->behavior,
!                                          stmt->missing_ok);
                              break;

                          default:
Index: src/include/commands/conversioncmds.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/commands/conversioncmds.h,v
retrieving revision 1.10
diff -c -r1.10 conversioncmds.h
*** src/include/commands/conversioncmds.h    28 Jun 2005 05:09:12 -0000    1.10
--- src/include/commands/conversioncmds.h    18 Nov 2005 20:39:54 -0000
***************
*** 18,24 ****
  #include "nodes/parsenodes.h"

  extern void CreateConversionCommand(CreateConversionStmt *parsetree);
! extern void DropConversionCommand(List *conversion_name, DropBehavior behavior);
  extern void RenameConversion(List *name, const char *newname);
  extern void AlterConversionOwner(List *name, Oid newOwnerId);

--- 18,25 ----
  #include "nodes/parsenodes.h"

  extern void CreateConversionCommand(CreateConversionStmt *parsetree);
! extern void DropConversionCommand(List *conversion_name,
!                                   DropBehavior behavior, bool missing_ok);
  extern void RenameConversion(List *name, const char *newname);
  extern void AlterConversionOwner(List *name, Oid newOwnerId);

Index: src/include/commands/schemacmds.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/commands/schemacmds.h,v
retrieving revision 1.10
diff -c -r1.10 schemacmds.h
*** src/include/commands/schemacmds.h    28 Jun 2005 05:09:12 -0000    1.10
--- src/include/commands/schemacmds.h    18 Nov 2005 20:39:54 -0000
***************
*** 19,25 ****

  extern void CreateSchemaCommand(CreateSchemaStmt *parsetree);

! extern void RemoveSchema(List *names, DropBehavior behavior);
  extern void RemoveSchemaById(Oid schemaOid);

  extern void RenameSchema(const char *oldname, const char *newname);
--- 19,25 ----

  extern void CreateSchemaCommand(CreateSchemaStmt *parsetree);

! extern void RemoveSchema(List *names, DropBehavior behavior, bool missing_ok);
  extern void RemoveSchemaById(Oid schemaOid);

  extern void RenameSchema(const char *oldname, const char *newname);
Index: src/include/commands/typecmds.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/commands/typecmds.h,v
retrieving revision 1.14
diff -c -r1.14 typecmds.h
*** src/include/commands/typecmds.h    15 Oct 2005 02:49:44 -0000    1.14
--- src/include/commands/typecmds.h    18 Nov 2005 20:39:54 -0000
***************
*** 20,29 ****
  #define DEFAULT_TYPDELIM        ','

  extern void DefineType(List *names, List *parameters);
! extern void RemoveType(List *names, DropBehavior behavior);
  extern void RemoveTypeById(Oid typeOid);
  extern void DefineDomain(CreateDomainStmt *stmt);
! extern void RemoveDomain(List *names, DropBehavior behavior);
  extern Oid    DefineCompositeType(const RangeVar *typevar, List *coldeflist);

  extern void AlterDomainDefault(List *names, Node *defaultRaw);
--- 20,29 ----
  #define DEFAULT_TYPDELIM        ','

  extern void DefineType(List *names, List *parameters);
! extern void RemoveType(List *names, DropBehavior behavior, bool missing_ok);
  extern void RemoveTypeById(Oid typeOid);
  extern void DefineDomain(CreateDomainStmt *stmt);
! extern void RemoveDomain(List *names, DropBehavior behavior, bool missing_ok);
  extern Oid    DefineCompositeType(const RangeVar *typevar, List *coldeflist);

  extern void AlterDomainDefault(List *names, Node *defaultRaw);
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.292
diff -c -r1.292 parsenodes.h
*** src/include/nodes/parsenodes.h    26 Oct 2005 19:21:55 -0000    1.292
--- src/include/nodes/parsenodes.h    18 Nov 2005 20:39:56 -0000
***************
*** 1278,1283 ****
--- 1278,1284 ----
      List       *objects;        /* list of sublists of names (as Values) */
      ObjectType    removeType;        /* object type */
      DropBehavior behavior;        /* RESTRICT or CASCADE behavior */
+     bool         missing_ok;    /* skip error if object is missing? */
  } DropStmt;

  /* ----------------------
Index: doc/src/sgml/ref/drop_conversion.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/drop_conversion.sgml,v
retrieving revision 1.8
diff -c -r1.8 drop_conversion.sgml
*** doc/src/sgml/ref/drop_conversion.sgml    29 Nov 2003 19:51:38 -0000    1.8
--- doc/src/sgml/ref/drop_conversion.sgml    18 Nov 2005 20:39:56 -0000
***************
*** 17,23 ****

   <refsynopsisdiv>
  <synopsis>
! DROP CONVERSION <replaceable>name</replaceable> [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

--- 17,23 ----

   <refsynopsisdiv>
  <synopsis>
! DROP CONVERSION [ IF EXISTS ] <replaceable>name</replaceable> [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

***************
*** 35,40 ****
--- 35,50 ----

     <variablelist>
      <varlistentry>
+      <term><literal>IF EXISTS</literal></term>
+      <listitem>
+       <para>
+        Do not throw an error if the conversion does not exist.
+        A notice is issued in this case.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><replaceable>name</replaceable></term>

       <listitem>
Index: doc/src/sgml/ref/drop_domain.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v
retrieving revision 1.15
diff -c -r1.15 drop_domain.sgml
*** doc/src/sgml/ref/drop_domain.sgml    2 May 2005 01:52:50 -0000    1.15
--- doc/src/sgml/ref/drop_domain.sgml    18 Nov 2005 20:39:56 -0000
***************
*** 20,26 ****

   <refsynopsisdiv>
  <synopsis>
! DROP DOMAIN <replaceable class="PARAMETER">name</replaceable> [, ...]  [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

--- 20,26 ----

   <refsynopsisdiv>
  <synopsis>
! DROP DOMAIN [IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...]  [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

***************
*** 38,43 ****
--- 38,53 ----

    <variablelist>
     <varlistentry>
+     <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.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term><replaceable class="PARAMETER">name</replaceable></term>
      <listitem>
       <para>
***************
*** 84,90 ****
    <title>Compatibility</title>

    <para>
!    This command conforms to the SQL standard.
    </para>
   </refsect1>

--- 94,102 ----
    <title>Compatibility</title>

    <para>
!    This command conforms to the SQL standard, except for the
!    <literal>IF EXISTS</> option, which is a <productname>PostgreSQL</>
!    extension.
    </para>
   </refsect1>

Index: doc/src/sgml/ref/drop_index.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/drop_index.sgml,v
retrieving revision 1.21
diff -c -r1.21 drop_index.sgml
*** doc/src/sgml/ref/drop_index.sgml    29 Nov 2003 19:51:38 -0000    1.21
--- doc/src/sgml/ref/drop_index.sgml    18 Nov 2005 20:39:56 -0000
***************
*** 20,26 ****

   <refsynopsisdiv>
  <synopsis>
! DROP INDEX <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

--- 20,26 ----

   <refsynopsisdiv>
  <synopsis>
! DROP INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

***************
*** 39,44 ****
--- 39,54 ----

    <variablelist>
     <varlistentry>
+     <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.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term><replaceable class="PARAMETER">name</replaceable></term>
      <listitem>
       <para>
Index: doc/src/sgml/ref/drop_schema.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/drop_schema.sgml,v
retrieving revision 1.6
diff -c -r1.6 drop_schema.sgml
*** doc/src/sgml/ref/drop_schema.sgml    29 Nov 2003 19:51:38 -0000    1.6
--- doc/src/sgml/ref/drop_schema.sgml    18 Nov 2005 20:39:57 -0000
***************
*** 20,26 ****

   <refsynopsisdiv>
  <synopsis>
! DROP SCHEMA <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

--- 20,26 ----

   <refsynopsisdiv>
  <synopsis>
! DROP SCHEMA [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

***************
*** 43,48 ****
--- 43,58 ----

    <variablelist>
     <varlistentry>
+     <term><literal>IF EXISTS</literal></term>
+     <listitem>
+      <para>
+       Do not throw an error if the schema does not exist. A notice is issued
+       in this case.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term><replaceable class="PARAMETER">name</replaceable></term>
      <listitem>
       <para>
***************
*** 92,98 ****
    <para>
     <command>DROP SCHEMA</command> is fully conforming with the SQL
     standard, except that the standard only allows one schema to be
!    dropped per command.
    </para>
   </refsect1>

--- 102,110 ----
    <para>
     <command>DROP SCHEMA</command> is fully conforming with the SQL
     standard, except that the standard only allows one schema to be
!    dropped per command, and apart from the
!    <literal>IF EXISTS</> option, which is a <productname>PostgreSQL</>
!    extension.
    </para>
   </refsect1>

Index: doc/src/sgml/ref/drop_sequence.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/drop_sequence.sgml,v
retrieving revision 1.23
diff -c -r1.23 drop_sequence.sgml
*** doc/src/sgml/ref/drop_sequence.sgml    1 Nov 2005 21:09:50 -0000    1.23
--- doc/src/sgml/ref/drop_sequence.sgml    18 Nov 2005 20:39:57 -0000
***************
*** 20,26 ****

   <refsynopsisdiv>
  <synopsis>
! DROP SEQUENCE <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

--- 20,26 ----

   <refsynopsisdiv>
  <synopsis>
! DROP SEQUENCE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

***************
*** 37,42 ****
--- 37,52 ----

    <variablelist>
     <varlistentry>
+     <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.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term><replaceable class="PARAMETER">name</replaceable></term>
      <listitem>
       <para>
***************
*** 84,90 ****
    <para>
     <command>DROP SEQUENCE</command> conforms to the <acronym>SQL</acronym>
     standard, except that the standard only allows one
!    sequence to be dropped per command.
    </para>
   </refsect1>

--- 94,102 ----
    <para>
     <command>DROP SEQUENCE</command> conforms to the <acronym>SQL</acronym>
     standard, except that the standard only allows one
!    sequence to be dropped per command, and apart from the
!    <literal>IF EXISTS</> option, which is a <productname>PostgreSQL</>
!    extension.
    </para>
   </refsect1>

Index: doc/src/sgml/ref/drop_table.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/drop_table.sgml,v
retrieving revision 1.22
diff -c -r1.22 drop_table.sgml
*** doc/src/sgml/ref/drop_table.sgml    4 Jan 2005 00:39:53 -0000    1.22
--- doc/src/sgml/ref/drop_table.sgml    18 Nov 2005 20:39:57 -0000
***************
*** 20,26 ****

   <refsynopsisdiv>
  <synopsis>
! DROP TABLE <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

--- 20,26 ----

   <refsynopsisdiv>
  <synopsis>
! DROP TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

***************
*** 49,54 ****
--- 49,64 ----

    <variablelist>
     <varlistentry>
+     <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.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term><replaceable class="PARAMETER">name</replaceable></term>
      <listitem>
       <para>
***************
*** 97,103 ****

    <para>
     This command conforms to the SQL standard, except that the standard only
!    allows one table to be dropped per command.
    </para>
   </refsect1>

--- 107,115 ----

    <para>
     This command conforms to the SQL standard, except that the standard only
!    allows one table to be dropped per command, and apart from the
!    <literal>IF EXISTS</> option, which is a <productname>PostgreSQL</>
!    extension.
    </para>
   </refsect1>

Index: doc/src/sgml/ref/drop_type.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/drop_type.sgml,v
retrieving revision 1.26
diff -c -r1.26 drop_type.sgml
*** doc/src/sgml/ref/drop_type.sgml    25 Jun 2004 21:55:50 -0000    1.26
--- doc/src/sgml/ref/drop_type.sgml    18 Nov 2005 20:39:57 -0000
***************
*** 20,26 ****

   <refsynopsisdiv>
  <synopsis>
! DROP TYPE <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

--- 20,26 ----

   <refsynopsisdiv>
  <synopsis>
! DROP TYPE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

***************
*** 38,43 ****
--- 38,53 ----

    <variablelist>
     <varlistentry>
+     <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.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term><replaceable class="PARAMETER">name</replaceable></term>
      <listitem>
       <para>
***************
*** 84,90 ****

    <para>
     This command is similar to the corresponding command in the SQL
!    standard, but note that the <command>CREATE TYPE</command> command
     and the data type extension mechanisms in
     <productname>PostgreSQL</productname> differ from the SQL standard.
    </para>
--- 94,102 ----

    <para>
     This command is similar to the corresponding command in the SQL
!    standard, aapart from the <literal>IF EXISTS</>
!    option, which is a <productname>PostgreSQL</> extension.
!    But note that the <command>CREATE TYPE</command> command
     and the data type extension mechanisms in
     <productname>PostgreSQL</productname> differ from the SQL standard.
    </para>
Index: doc/src/sgml/ref/drop_view.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/drop_view.sgml,v
retrieving revision 1.21
diff -c -r1.21 drop_view.sgml
*** doc/src/sgml/ref/drop_view.sgml    4 Jan 2005 00:39:53 -0000    1.21
--- doc/src/sgml/ref/drop_view.sgml    18 Nov 2005 20:39:57 -0000
***************
*** 20,26 ****

   <refsynopsisdiv>
  <synopsis>
! DROP VIEW <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

--- 20,26 ----

   <refsynopsisdiv>
  <synopsis>
! DROP VIEW [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>

***************
*** 38,43 ****
--- 38,53 ----

    <variablelist>
     <varlistentry>
+     <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.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term><replaceable class="PARAMETER">name</replaceable></term>
      <listitem>
       <para>
***************
*** 84,90 ****

    <para>
     This command conforms to the SQL standard, except that the standard only
!    allows one view to be dropped per command.
    </para>
   </refsect1>

--- 94,102 ----

    <para>
     This command conforms to the SQL standard, except that the standard only
!    allows one view to be dropped per command, and apart from the
!    <literal>IF EXISTS</> option, which is a <productname>PostgreSQL</>
!    extension.
    </para>
   </refsect1>


pgsql-patches by date:

Previous
From: Alvaro Herrera
Date:
Subject: DROP OWNED again
Next
From: Tom Lane
Date:
Subject: Re: drop if exists - first piece