Add support for DROP TABLE IF EXISTS. (CVS 2843)

FossilOrigin-Name: a4c547de83d8b27f06a58f9e530a7c983ec1dc3a
diff --git a/src/build.c b/src/build.c
index 38f5802..39de2fd 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.361 2005/12/21 18:36:46 drh Exp $
+** $Id: build.c,v 1.362 2005/12/29 01:11:37 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1754,7 +1754,7 @@
 ** This routine is called to do the work of a DROP TABLE statement.
 ** pName is the name of the table to be dropped.
 */
-void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
+void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
   Table *pTab;
   Vdbe *v;
   sqlite3 *db = pParse->db;
@@ -1764,7 +1764,12 @@
   assert( pName->nSrc==1 );
   pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);
 
-  if( pTab==0 ) goto exit_drop_table;
+  if( pTab==0 ){
+    if( noErr ){
+      sqlite3ErrorClear(pParse);
+    }
+    goto exit_drop_table;
+  }
   iDb = pTab->iDb;
   assert( iDb>=0 && iDb<db->nDb );
 #ifndef SQLITE_OMIT_AUTHORIZATION
diff --git a/src/parse.y b/src/parse.y
index f000a6f..7fd8aa1 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.188 2005/12/16 01:06:17 drh Exp $
+** @(#) $Id: parse.y,v 1.189 2005/12/29 01:11:37 drh Exp $
 */
 
 // All token codes are small integers with #defines that begin with "TK_"
@@ -172,7 +172,7 @@
 %ifdef SQLITE_OMIT_COMPOUND_SELECT
   EXCEPT INTERSECT UNION
 %endif
-  REINDEX RENAME CTIME_KW
+  REINDEX RENAME CTIME_KW IF
   .
 
 // Define operator precedence early so that this is the first occurance
@@ -336,9 +336,12 @@
 
 ////////////////////////// The DROP TABLE /////////////////////////////////////
 //
-cmd ::= DROP TABLE fullname(X). {
-  sqlite3DropTable(pParse, X, 0);
+cmd ::= DROP TABLE ifexists(E) fullname(X). {
+  sqlite3DropTable(pParse, X, 0, E);
 }
+%type ifexists {int}
+ifexists(A) ::= IF EXISTS.   {A = 1;}
+ifexists(A) ::= .            {A = 0;}
 
 ///////////////////// The CREATE VIEW statement /////////////////////////////
 //
@@ -346,8 +349,8 @@
 cmd ::= CREATE(X) temp(T) VIEW nm(Y) dbnm(Z) AS select(S). {
   sqlite3CreateView(pParse, &X, &Y, &Z, S, T);
 }
-cmd ::= DROP VIEW fullname(X). {
-  sqlite3DropTable(pParse, X, 1);
+cmd ::= DROP VIEW ifexists(E) fullname(X). {
+  sqlite3DropTable(pParse, X, 1, E);
 }
 %endif // SQLITE_OMIT_VIEW
 
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 5664ead..b5ff1c2 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.442 2005/12/20 09:19:37 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.443 2005/12/29 01:11:37 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1448,6 +1448,7 @@
 void *sqlite3TextToPtr(const char*);
 void sqlite3SetString(char **, ...);
 void sqlite3ErrorMsg(Parse*, const char*, ...);
+void sqlite3ErrorClear(Parse*);
 void sqlite3Dequote(char*);
 void sqlite3DequoteExpr(Expr*);
 int sqlite3KeywordCode(const unsigned char*, int);
@@ -1488,7 +1489,7 @@
 # define sqlite3ViewGetColumnNames(A,B) 0
 #endif
 
-void sqlite3DropTable(Parse*, SrcList*, int);
+void sqlite3DropTable(Parse*, SrcList*, int, int);
 void sqlite3DeleteTable(sqlite3*, Table*);
 void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
 int sqlite3ArrayAllocate(void**,int,int);
diff --git a/src/util.c b/src/util.c
index 776f5db..898d3de 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.158 2005/12/20 14:38:00 danielk1977 Exp $
+** $Id: util.c,v 1.159 2005/12/29 01:11:37 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -762,6 +762,15 @@
 }
 
 /*
+** Clear the error message in pParse, if any
+*/
+void sqlite3ErrorClear(Parse *pParse){
+  sqliteFree(pParse->zErrMsg);
+  pParse->zErrMsg = 0;
+  pParse->nErr = 0;
+}
+
+/*
 ** Convert an SQL-style quoted string into a normal string by removing
 ** the quote characters.  The conversion is done in-place.  If the
 ** input does not begin with a quote character, then this routine
@@ -1331,5 +1340,3 @@
   sqlite3Tsd()->mallocAllowed = 1;
 }
 #endif
-
-