Add support for CREATE TABLE IF NOT EXISTS. (CVS 2847)

FossilOrigin-Name: 0bd9e35fd22946640f4fb1c1874922ae096916f7
diff --git a/src/build.c b/src/build.c
index b0e8100..655fee5 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.363 2005/12/29 19:23:07 drh Exp $
+** $Id: build.c,v 1.364 2005/12/29 23:33:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -635,7 +635,8 @@
   Token *pName1,   /* First part of the name of the table or view */
   Token *pName2,   /* Second part of the name of the table or view */
   int isTemp,      /* True if this is a TEMP table */
-  int isView       /* True if this is a VIEW */
+  int isView,      /* True if this is a VIEW */
+  int noErr        /* Do nothing if table already exists */
 ){
   Table *pTable;
   char *zName = 0; /* The name of the new table */
@@ -713,7 +714,9 @@
   }
   pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
   if( pTable ){
-    sqlite3ErrorMsg(pParse, "table %T already exists", pName);
+    if( !noErr ){
+      sqlite3ErrorMsg(pParse, "table %T already exists", pName);
+    }
     goto begin_table_error;
   }
   if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){
@@ -1505,7 +1508,7 @@
     sqlite3SelectDelete(pSelect);
     return;
   }
-  sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1);
+  sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1, 0);
   p = pParse->pNewTable;
   if( p==0 || pParse->nErr ){
     sqlite3SelectDelete(pSelect);
diff --git a/src/parse.y b/src/parse.y
index 7fd8aa1..1300575 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.189 2005/12/29 01:11:37 drh Exp $
+** @(#) $Id: parse.y,v 1.190 2005/12/29 23:33:54 drh Exp $
 */
 
 // All token codes are small integers with #defines that begin with "TK_"
@@ -120,9 +120,12 @@
 ///////////////////// The CREATE TABLE statement ////////////////////////////
 //
 cmd ::= create_table create_table_args.
-create_table ::= CREATE(X) temp(T) TABLE nm(Y) dbnm(Z). {
-   sqlite3StartTable(pParse,&X,&Y,&Z,T,0);
+create_table ::= CREATE(X) temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). {
+   sqlite3StartTable(pParse,&X,&Y,&Z,T,0,E);
 }
+%type ifnotexists {int}
+ifnotexists(A) ::= .              {A = 0;}
+ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
 %type temp {int}
 %ifndef SQLITE_OMIT_TEMPDB
 temp(A) ::= TEMP.  {A = 1;}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 2737c1d..6868e24 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.444 2005/12/29 19:23:07 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.445 2005/12/29 23:33:54 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1482,7 +1482,7 @@
 void sqlite3CommitInternalChanges(sqlite3*);
 Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
 void sqlite3OpenMasterTable(Vdbe *v, int);
-void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
+void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int,int);
 void sqlite3AddColumn(Parse*,Token*);
 void sqlite3AddNotNull(Parse*, int);
 void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);