Обсуждение: drop if exists

Поиск
Список
Период
Сортировка

drop if exists

От
Andrew Dunstan
Дата:
Ther attached patch is for comment. It implements "drop if exists" as
has recently been discussed. Illustration:

andrew=# drop table blurflx;
ERROR:  table "blurflx" does not exist
andrew=# drop table if exists blurflx;
DROP TABLE
andrew=# create table blurflx ( x text);
CREATE TABLE
andrew=# drop table if exists blurflx;
DROP TABLE
andrew=# drop table blurflx;
ERROR:  table "blurflx" does not exist
andrew=#

If the patch is acceptable I will work up some documentation and
regression tests.

cheers

andrew
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    14 Nov 2005 14:09:52 -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,118 ----
   * DROP CONVERSION
   */
  void
! DropConversionCommand(List *name, DropBehavior behavior, bool missing_ok)
  {
      Oid            conversionOid;

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

      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    14 Nov 2005 14:09:52 -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,176 ----
                                   CStringGetDatum(namespaceName),
                                   0, 0, 0);
      if (!OidIsValid(namespaceId))
!     {
!         if (missing_ok)
!             return;
!         else
!             ereport(ERROR,
!                     (errcode(ERRCODE_UNDEFINED_SCHEMA),
!                      errmsg("schema \"%s\" does not exist", namespaceName)));
!     }

      /* 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    14 Nov 2005 14:09:54 -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,428 ----
      /* Use LookupTypeName here so that shell types can be removed. */
      typeoid = LookupTypeName(typename);
      if (!OidIsValid(typeoid))
!     {
!         if (missing_ok)
!             return;
!         else
!             ereport(ERROR,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("type \"%s\" does not exist",
!                             TypeNameToString(typename))));
!     }

      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;
--- 784,790 ----
   * 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),
--- 801,815 ----
      /* Use LookupTypeName here so that shell types can be removed. */
      typeoid = LookupTypeName(typename);
      if (!OidIsValid(typeoid))
!     {
!         if (missing_ok)
!             return;
!         else
!             ereport(ERROR,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("type \"%s\" does not exist",
!                             TypeNameToString(typename))));
!     }

      tup = SearchSysCache(TYPEOID,
                           ObjectIdGetDatum(typeoid),
Index: src/backend/parser/gram.y
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.511
diff -c -r2.511 gram.y
*** src/backend/parser/gram.y    23 Sep 2005 22:25:25 -0000    2.511
--- src/backend/parser/gram.y    14 Nov 2005 14:10:00 -0000
***************
*** 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
***************
*** 2822,2837 ****
   *
   *****************************************************************************/

! 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; }
--- 2822,2848 ----
   *
   *****************************************************************************/

! 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; }
***************
*** 8149,8154 ****
--- 8160,8166 ----
              | 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    14 Nov 2005 14:10:00 -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    14 Nov 2005 14:10:00 -0000
***************
*** 147,154 ****
      Assert(false);                /* Should be impossible */
  }

! static void
! CheckDropPermissions(RangeVar *rel, char rightkind)
  {
      Oid            relOid;
      HeapTuple    tuple;
--- 147,161 ----
      Assert(false);                /* Should be impossible */
  }

! /*
!  * 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),
--- 163,174 ----

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

      tuple = SearchSysCache(RELOID,
                             ObjectIdGetDatum(relOid),
***************
*** 183,188 ****
--- 195,202 ----
                          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:
--- 542,577 ----
                      {
                          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:
--- 579,591 ----
                              /*
                               * 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:
--- 593,600 ----
                              /*
                               * 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    14 Nov 2005 14:10:02 -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    14 Nov 2005 14:10:02 -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    14 Nov 2005 14:10:02 -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    14 Nov 2005 14:10:04 -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;

  /* ----------------------

Re: drop if exists

От
Michael Glaesemann
Дата:
On Nov 14, 2005, at 23:25 , Andrew Dunstan wrote:

>
> Ther attached patch is for comment. It implements "drop if exists"
> as has recently been discussed. Illustration:

Nifty! Thanks for working this up, Andrew!


> andrew=# drop table blurflx;
> ERROR:  table "blurflx" does not exist
> andrew=# drop table if exists blurflx;
> DROP TABLE

I'm not sure what other DBMS' return in this situation (and kindly
ignore this suggestion if it's specified or otherwise determined),
but perhaps the output could be TABLE "blurlx" DOES NOT EXIST
(without the ERROR) or something more informative, rather than DROP
TABLE. It reminds me of the old behavior of outputting COMMIT even in
the case of transaction failure. I find the current behavior of
outputting ROLLBACK in the case of transaction failure more useful.

Michael Glaesemann
grzm myrealbox com




Re: drop if exists

От
"Dave Page"
Дата:

> -----Original Message-----
> From: pgsql-patches-owner@postgresql.org
> [mailto:pgsql-patches-owner@postgresql.org] On Behalf Of
> Michael Glaesemann
> Sent: 14 November 2005 14:54
> To: Andrew Dunstan
> Cc: Patches (PostgreSQL)
> Subject: Re: [PATCHES] drop if exists
>
>
> On Nov 14, 2005, at 23:25 , Andrew Dunstan wrote:
>
> >
> > Ther attached patch is for comment. It implements "drop if exists"
> > as has recently been discussed. Illustration:
>
> Nifty! Thanks for working this up, Andrew!
>
>
> > andrew=# drop table blurflx;
> > ERROR:  table "blurflx" does not exist
> > andrew=# drop table if exists blurflx;
> > DROP TABLE
>
> I'm not sure what other DBMS' return in this situation (and kindly
> ignore this suggestion if it's specified or otherwise determined),
> but perhaps the output could be TABLE "blurlx" DOES NOT EXIST
> (without the ERROR) or something more informative, rather than DROP
> TABLE. It reminds me of the old behavior of outputting COMMIT
> even in
> the case of transaction failure. I find the current behavior of
> outputting ROLLBACK in the case of transaction failure more useful.

Yes, a notice would certainly be nice:

andrew=# drop table blurflx;
ERROR:  table "blurflx" does not exist
andrew=# drop table if exists blurflx;
NOTICE: table "blurflx" does not exist
DROP TABLE

Regards, Dave.

Re: drop if exists

От
Tom Lane
Дата:
Andrew Dunstan <andrew@dunslane.net> writes:
> andrew=# drop table blurflx;
> ERROR:  table "blurflx" does not exist
> andrew=# drop table if exists blurflx;
> DROP TABLE

If I read MySQL's documentation correctly, they emit a NOTE (equivalent
of a NOTICE message I suppose) when IF EXISTS does nothing because the
table doesn't exist.  Seems like we should do likewise --- your second
example here seems actively misleading.  That is, I'd rather see

andrew=# drop table if exists blurflx;
NOTICE:  table "blurflx" does not exist, skipping
DROP TABLE


            regards, tom lane

Re: drop if exists

От
Andrew Dunstan
Дата:
OK, now it looks like this:

andrew=# drop table blurflx;
ERROR:  table "blurflx" does not exist
andrew=# drop table if exists blurflx;
NOTICE:  table "blurflx" does not exist, skipping
DROP TABLE
andrew=# create table blurflx ( x text);
CREATE TABLE
andrew=# drop table if exists blurflx;
DROP TABLE
andrew=# drop table blurflx;
ERROR:  table "blurflx" does not exist
andrew=#

revised patch attached.

cheers

andrew

Tom Lane wrote:

>Andrew Dunstan <andrew@dunslane.net> writes:
>
>
>>andrew=# drop table blurflx;
>>ERROR:  table "blurflx" does not exist
>>andrew=# drop table if exists blurflx;
>>DROP TABLE
>>
>>
>
>If I read MySQL's documentation correctly, they emit a NOTE (equivalent
>of a NOTICE message I suppose) when IF EXISTS does nothing because the
>table doesn't exist.  Seems like we should do likewise --- your second
>example here seems actively misleading.  That is, I'd rather see
>
>andrew=# drop table if exists blurflx;
>NOTICE:  table "blurflx" does not exist, skipping
>DROP TABLE
>
>
>            regards, tom lane
>
>
>
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    14 Nov 2005 17:00:05 -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    14 Nov 2005 17:00:05 -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    14 Nov 2005 17:00:05 -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,825 ----
      /* Use LookupTypeName here so that shell types can be removed. */
      typeoid = LookupTypeName(typename);
      if (!OidIsValid(typeoid))
!     {
!         if (missing_ok)
!             return;
!         else
!             ereport(ERROR,
!                     (errcode(ERRCODE_UNDEFINED_OBJECT),
!                      errmsg("type \"%s\" does not exist",
!                             TypeNameToString(typename))));
!     }

      tup = SearchSysCache(TYPEOID,
                           ObjectIdGetDatum(typeoid),
Index: src/backend/parser/gram.y
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.511
diff -c -r2.511 gram.y
*** src/backend/parser/gram.y    23 Sep 2005 22:25:25 -0000    2.511
--- src/backend/parser/gram.y    14 Nov 2005 17:00:13 -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
***************
*** 2822,2837 ****
   *
   *****************************************************************************/

! 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; }
--- 2822,2848 ----
   *
   *****************************************************************************/

! 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; }
***************
*** 8149,8154 ****
--- 8160,8166 ----
              | 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    14 Nov 2005 17:00:13 -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    14 Nov 2005 17:00:15 -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    14 Nov 2005 17:00:18 -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    14 Nov 2005 17:00:18 -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    14 Nov 2005 17:00:18 -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    14 Nov 2005 17:00:20 -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;

  /* ----------------------

Re: drop if exists

От
Bruce Momjian
Дата:
Removed from queue.  Andrew is committing it.

---------------------------------------------------------------------------

Andrew Dunstan wrote:
>
> OK, now it looks like this:
>
> andrew=# drop table blurflx;
> ERROR:  table "blurflx" does not exist
> andrew=# drop table if exists blurflx;
> NOTICE:  table "blurflx" does not exist, skipping
> DROP TABLE
> andrew=# create table blurflx ( x text);
> CREATE TABLE
> andrew=# drop table if exists blurflx;
> DROP TABLE
> andrew=# drop table blurflx;
> ERROR:  table "blurflx" does not exist
> andrew=#
>
> revised patch attached.
>
> cheers
>
> andrew
>
> Tom Lane wrote:
>
> >Andrew Dunstan <andrew@dunslane.net> writes:
> >
> >
> >>andrew=# drop table blurflx;
> >>ERROR:  table "blurflx" does not exist
> >>andrew=# drop table if exists blurflx;
> >>DROP TABLE
> >>
> >>
> >
> >If I read MySQL's documentation correctly, they emit a NOTE (equivalent
> >of a NOTICE message I suppose) when IF EXISTS does nothing because the
> >table doesn't exist.  Seems like we should do likewise --- your second
> >example here seems actively misleading.  That is, I'd rather see
> >
> >andrew=# drop table if exists blurflx;
> >NOTICE:  table "blurflx" does not exist, skipping
> >DROP TABLE
> >
> >
> >            regards, tom lane
> >
> >
> >


>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
>                http://archives.postgresql.org

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Re: drop if exists

От
Christopher Kings-Lynne
Дата:
Will we get this functionality for ALL objects?

Bruce Momjian wrote:
> Removed from queue.  Andrew is committing it.
>
> ---------------------------------------------------------------------------
>
> Andrew Dunstan wrote:
>
>>OK, now it looks like this:
>>
>>andrew=# drop table blurflx;
>>ERROR:  table "blurflx" does not exist
>>andrew=# drop table if exists blurflx;
>>NOTICE:  table "blurflx" does not exist, skipping
>>DROP TABLE
>>andrew=# create table blurflx ( x text);
>>CREATE TABLE
>>andrew=# drop table if exists blurflx;
>>DROP TABLE
>>andrew=# drop table blurflx;
>>ERROR:  table "blurflx" does not exist
>>andrew=#
>>
>>revised patch attached.
>>
>>cheers
>>
>>andrew
>>
>>Tom Lane wrote:
>>
>>
>>>Andrew Dunstan <andrew@dunslane.net> writes:
>>>
>>>
>>>
>>>>andrew=# drop table blurflx;
>>>>ERROR:  table "blurflx" does not exist
>>>>andrew=# drop table if exists blurflx;
>>>>DROP TABLE
>>>>
>>>>
>>>
>>>If I read MySQL's documentation correctly, they emit a NOTE (equivalent
>>>of a NOTICE message I suppose) when IF EXISTS does nothing because the
>>>table doesn't exist.  Seems like we should do likewise --- your second
>>>example here seems actively misleading.  That is, I'd rather see
>>>
>>>andrew=# drop table if exists blurflx;
>>>NOTICE:  table "blurflx" does not exist, skipping
>>>DROP TABLE
>>>
>>>
>>>            regards, tom lane
>>>
>>>
>>>
>
>
>
>>---------------------------(end of broadcast)---------------------------
>>TIP 4: Have you searched our list archives?
>>
>>               http://archives.postgresql.org
>
>


Re: drop if exists

От
"Andrew Dunstan"
Дата:
Christopher Kings-Lynne said:
> Will we get this functionality for ALL objects?
>

The patch does these: table, view, index, sequence, schema, type, domain,
and conversion. The reason is that these are all dealt with using the same
bit of the grammar, and the first 4 are pretty much completely done by the
same code.

I think anything else will have to be done individually, although the
pattern can be copied.

Perhaps we should take bids on what should/should not be covered.

cheers

andrew




Re: drop if exists

От
Christopher Kings-Lynne
Дата:
> I think anything else will have to be done individually, although the
> pattern can be copied.
>
> Perhaps we should take bids on what should/should not be covered.

Everything should be covered, otherwise it's just annoying for users...

Chris


Re: drop if exists

От
Michael Glaesemann
Дата:
On Nov 17, 2005, at 11:45 , Christopher Kings-Lynne wrote:

>> I think anything else will have to be done individually, although the
>> pattern can be copied.
>> Perhaps we should take bids on what should/should not be covered.
>
> Everything should be covered, otherwise it's just annoying for
> users...

Including objects that already have CREATE OR REPLACE?

Michael Glaesemann
grzm myrealbox com




Re: drop if exists

От
Christopher Kings-Lynne
Дата:
> Including objects that already have CREATE OR REPLACE?

I assume so - CREATE OR REPLACE doesn't drop things - only creates or
replaces them.

Chris


Re: drop if exists

От
Andrew Dunstan
Дата:

Christopher Kings-Lynne wrote:

>> I think anything else will have to be done individually, although the
>> pattern can be copied.
>>
>> Perhaps we should take bids on what should/should not be covered.
>
>
> Everything should be covered, otherwise it's just annoying for users...


Well, that's arguably more than I originally signed up for ;-) See

http://archives.postgresql.org/pgsql-hackers/2005-10/msg00632.php

There are currently DROP commends for the following 21 objects
(according to the docs).

AGGREGATE
CAST
CONVERSION
DATABASE
DOMAIN
FUNCTION
GROUP
INDEX
LANGUAGE
OPERATOR
OPERATOR CLASS
ROLE
RULE
SCHEMA
SEQUENCE
TABLE
TABLESPACE
TRIGGER
TYPE
USER
VIEW

If the consensus is to add this to all of them, then I propose to apply
the patch I have (with a slight fix for an oversight in the case of
domains, plus docs and tests) for the 8 cases and start working on the
remaining 13 as time permits. To be honest, I have not even looked at
those 13 cases.

One motivation for this, besides general utility, is to ease MySQL
migrations, btw, and AFAICT they only have three DROP commands and only
two of them (TABLE and DATABASE) have IF EXISTS - DROP INDEX does not
for some reason - probably because it is actually mapped to an ALTER
TABLE statement.

cheers

andrew



Re: drop if exists

От
Michael Glaesemann
Дата:
On Nov 17, 2005, at 11:51 , Christopher Kings-Lynne wrote:

>> Including objects that already have CREATE OR REPLACE?
>
> I assume so - CREATE OR REPLACE doesn't drop things - only creates
> or replaces them.

Of course. Silly me :)

Michael Glaesemann
grzm myrealbox com




Re: drop if exists

От
Christopher Kings-Lynne
Дата:
> If the consensus is to add this to all of them, then I propose to apply
> the patch I have (with a slight fix for an oversight in the case of
> domains, plus docs and tests) for the 8 cases and start working on the
> remaining 13 as time permits. To be honest, I have not even looked at
> those 13 cases.

I agree.  I can have a crack at the others as well.  It's in my area of
ability I hope ;)  (Except grammar janking)

Chris