More bugs fixed for views. (CVS 416)

FossilOrigin-Name: 813077623087ffc6cd506f57cf6d1e3d9239f806
diff --git a/src/btree.c b/src/btree.c
index 0e8a269..de288f9 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.57 2002/03/02 20:41:58 drh Exp $
+** $Id: btree.c,v 1.58 2002/03/03 23:06:01 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -2988,6 +2988,7 @@
   /* Check all the tables.
   */
   for(i=0; i<nRoot; i++){
+    if( aRoot[i]==0 ) continue;
     checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0);
   }
 
diff --git a/src/build.c b/src/build.c
index 250872f..adc07cb 100644
--- a/src/build.c
+++ b/src/build.c
@@ -25,7 +25,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.82 2002/03/03 18:59:40 drh Exp $
+** $Id: build.c,v 1.83 2002/03/03 23:06:01 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -753,18 +753,28 @@
   ** make an entry in SQLITE_MASTER.
   */
   if( !pParse->initFlag ){
-    int n, addr;
+    int n;
     Vdbe *v;
 
     v = sqliteGetVdbe(pParse);
     if( v==0 ) return;
-    addr = sqliteVdbeAddOp(v, OP_CreateTable, 0, p->isTemp);
-    sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, P3_POINTER);
+    if( p->pSelect==0 ){
+      /* A regular table */
+      sqliteVdbeAddOp(v, OP_CreateTable, 0, p->isTemp);
+      sqliteVdbeChangeP3(v, -1, (char *)&p->tnum, P3_POINTER);
+    }else{
+      /* A view */
+      sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+    }
     p->tnum = 0;
     if( !p->isTemp ){
       sqliteVdbeAddOp(v, OP_Pull, 1, 0);
       sqliteVdbeAddOp(v, OP_String, 0, 0);
-      sqliteVdbeChangeP3(v, -1, "table", P3_STATIC);
+      if( p->pSelect==0 ){
+        sqliteVdbeChangeP3(v, -1, "table", P3_STATIC);
+      }else{
+        sqliteVdbeChangeP3(v, -1, "view", P3_STATIC);
+      }
       sqliteVdbeAddOp(v, OP_String, 0, 0);
       sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
       sqliteVdbeAddOp(v, OP_String, 0, 0);
@@ -808,7 +818,7 @@
 ){
   Token sEnd;
   Table *p;
-  char *z;
+  const char *z;
   int n, offset;
 
   sqliteStartTable(pParse, pBegin, pName, 0);
@@ -829,7 +839,11 @@
   }
   sEnd.n = 0;
   n = ((int)sEnd.z) - (int)pBegin->z;
-  z = p->pSelect->zSelect = sqliteStrNDup(pBegin->z, n+1);
+  z = pBegin->z;
+  while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
+  sEnd.z = &z[n-1];
+  sEnd.n = 1;
+  z = p->pSelect->zSelect = sqliteStrNDup(z, n);
   if( z ){
     offset = ((int)z) - (int)pBegin->z;
     sqliteSelectMoveStrings(p->pSelect, offset);
@@ -966,7 +980,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 sqliteDropTable(Parse *pParse, Token *pName){
+void sqliteDropTable(Parse *pParse, Token *pName, int isView){
   Table *pTable;
   Vdbe *v;
   int base;
@@ -981,6 +995,18 @@
     pParse->nErr++;
     return;
   }
+  if( isView && pTable->pSelect==0 ){
+    sqliteSetString(&pParse->zErrMsg, "use DROP TABLE to delete table ",
+      pTable->zName, 0);
+    pParse->nErr++;
+    return;
+  }
+  if( !isView && pTable->pSelect ){
+    sqliteSetString(&pParse->zErrMsg, "use DROP VIEW to delete view ",
+      pTable->zName, 0);
+    pParse->nErr++;
+    return;
+  }
 
   /* Generate code to remove the table from the master table
   ** on disk.
@@ -1008,9 +1034,11 @@
       changeCookie(db);
       sqliteVdbeChangeP1(v, base+9, db->next_cookie);
     }
-    sqliteVdbeAddOp(v, OP_Destroy, pTable->tnum, pTable->isTemp);
-    for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
-      sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pTable->isTemp);
+    if( !isView ){
+      sqliteVdbeAddOp(v, OP_Destroy, pTable->tnum, pTable->isTemp);
+      for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
+        sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pTable->isTemp);
+      }
     }
     sqliteEndWriteOperation(pParse);
   }
@@ -1871,7 +1899,7 @@
       { OP_Next,        0, 3,        0},
       { OP_IntegrityCk, 0, 0,        0},
       { OP_ColumnCount, 1, 0,        0},
-      { OP_ColumnName,  0, 0,        "sanity_check"},
+      { OP_ColumnName,  0, 0,        "integrity_check"},
       { OP_Callback,    1, 0,        0},
     };
     Vdbe *v = sqliteGetVdbe(pParse);
diff --git a/src/parse.y b/src/parse.y
index 6e3f45c..7a2f13b 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.54 2002/03/02 17:04:08 drh Exp $
+** @(#) $Id: parse.y,v 1.55 2002/03/03 23:06:01 drh Exp $
 */
 %token_prefix TK_
 %token_type {Token}
@@ -188,7 +188,7 @@
 
 ////////////////////////// The DROP TABLE /////////////////////////////////////
 //
-cmd ::= DROP TABLE ids(X).          {sqliteDropTable(pParse,&X);}
+cmd ::= DROP TABLE ids(X).          {sqliteDropTable(pParse,&X,0);}
 
 ///////////////////// The CREATE VIEW statement /////////////////////////////
 //
@@ -196,7 +196,7 @@
   sqliteCreateView(pParse, &X, &Y, S);
 }
 cmd ::= DROP VIEW ids(X). {
-  sqliteDropTable(pParse, &X);
+  sqliteDropTable(pParse, &X, 1);
 }
 
 //////////////////////// The SELECT statement /////////////////////////////////
diff --git a/src/shell.c b/src/shell.c
index 959412a..b2368d0 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -12,7 +12,7 @@
 ** This file contains code to implement the "sqlite" command line
 ** utility for accessing SQLite databases.
 **
-** $Id: shell.c,v 1.46 2002/02/26 23:24:27 drh Exp $
+** $Id: shell.c,v 1.47 2002/03/03 23:06:01 drh Exp $
 */
 #include <stdlib.h>
 #include <string.h>
@@ -721,14 +721,14 @@
     if( nArg==1 ){
       rc = sqlite_get_table(db,
         "SELECT name FROM sqlite_master "
-        "WHERE type='table' "
+        "WHERE type IN ('table','view') "
         "ORDER BY name",
         &azResult, &nRow, 0, &zErrMsg
       );
     }else{
       rc = sqlite_get_table_printf(db,
         "SELECT name FROM sqlite_master "
-        "WHERE type='table' AND name LIKE '%%%q%%' "
+        "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
         "ORDER BY name",
         &azResult, &nRow, 0, &zErrMsg, azArg[1]
       );
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index cdc7a0c..4dd693c 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.100 2002/03/03 18:59:41 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.101 2002/03/03 23:06:02 drh Exp $
 */
 #include "sqlite.h"
 #include "hash.h"
@@ -586,7 +586,7 @@
 void sqliteCreateView(Parse*,Token*,Token*,Select*);
 int sqliteViewGetColumnNames(Parse*,Table*);
 void sqliteViewResetAll(sqlite*);
-void sqliteDropTable(Parse*, Token*);
+void sqliteDropTable(Parse*, Token*, int);
 void sqliteDeleteTable(sqlite*, Table*);
 void sqliteInsert(Parse*, Token*, ExprList*, Select*, IdList*, int);
 IdList *sqliteIdListAppend(IdList*, Token*);