]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Create table now works with sqlite3NestedParse. This changed uncovered
authordrh <drh@noemail.net>
Fri, 5 Nov 2004 17:17:50 +0000 (17:17 +0000)
committerdrh <drh@noemail.net>
Fri, 5 Nov 2004 17:17:50 +0000 (17:17 +0000)
a latent bug in xprintf which is also fixed. (CVS 2069)

FossilOrigin-Name: b0506bdd701339d63166ada065445776dd499588

manifest
manifest.uuid
src/build.c
src/delete.c
src/insert.c
src/printf.c
src/sqliteInt.h
src/update.c
src/vdbeaux.c

index b0963e30c5cf78b1d3e710e75a373efd7eefd81d..67f06c361560e88d1227c775b57f83347ba6d283 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Do\snot\struncate\sa\sdatabase\sfile\suntil\safter\sfsync()\shas\sbeen\scalled\son\sthe\sjournal.\s(CVS\s2068)
-D 2004-11-05T16:37:03
+C Create\stable\snow\sworks\swith\ssqlite3NestedParse.\s\sThis\schanged\suncovered\na\slatent\sbug\sin\sxprintf\swhich\sis\salso\sfixed.\s(CVS\s2069)
+D 2004-11-05T17:17:50
 F Makefile.in c4d2416860f472a1e3393714d0372074197565df
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
@@ -31,14 +31,14 @@ F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
 F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
 F src/btree.c bf0d3d59ec076f0a37378f8ac6090d157d925c24
 F src/btree.h 861e40b759a195ba63819740e484390012cf81ab
-F src/build.c dc8b9ab836f2323d9b313c2d703b00b2e9441382
+F src/build.c f204aebf587f4543102dc6ea7c9283cb5949d7f0
 F src/date.c 34bdb0082db7ec2a83ef00063f7b44e61ee19dad
-F src/delete.c 6a54fd9f0fa6b93e13e40368a8b7206e3aae760c
+F src/delete.c f0af21a1ede15524a5edd59fe10ef486283a1ee9
 F src/expr.c be18081d2959a2cc53846d0fbedfec40fbfa1d6e
 F src/func.c 600e506bccf7648df8ad03efb417560d0f7ad4c1
 F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
-F src/insert.c b6ad8e90153ffb0c03bb7a0e04b14f8ddf096d92
+F src/insert.c 3fd6e00c9f62ad14daa94c75ae9971c32119f97e
 F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
 F src/main.c ba1b26f03af4b7f8be3394748123dd671b9ea147
 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
@@ -56,12 +56,12 @@ F src/pager.c 868c67e4ff8a1785c06caaf483fddb5a95013af0
 F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
 F src/parse.y 97247c0a89ca1667729db5035f1ee60140960984
 F src/pragma.c 6a0ae7721e614c5a921e918ab5206d5e654f1a6f
-F src/printf.c 7a92adc00b758cd5ce087dae80181a8bbdb70ed2
+F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c 156990c636102bb6b8de85e7ff3396a62568476b
 F src/shell.c 55adda3cf3c1cc2f6c1919aac17b2318f9c2a96f
 F src/sqlite.h.in 4f97b5907acfd2a5068cb0cec9d5178816734db7
-F src/sqliteInt.h 14b36d195ad418fc3d390e36a59ec0e3d0a1bdc7
+F src/sqliteInt.h 5d26b41b2ab7eeab1bd9db330ed7b7929d2ae875
 F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
 F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
 F src/test1.c df1d1ca2c40cafefb9a29860f072c4d0fee1a7b5
@@ -71,7 +71,7 @@ F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
 F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
 F src/tokenize.c c48221284e729be067237a8cfd7848fb62ee4a92
 F src/trigger.c f9a0a8d3a87238de1a934eeb7d0b6b1f13e6a55b
-F src/update.c 50ac56ab8109846eda843591d63527c94e862bc3
+F src/update.c 3cc67f6053495152e82a6a48c93ed331218e936e
 F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
 F src/util.c 005fdf2d008f3429d081766ad6098fdd86d8d8e6
 F src/vacuum.c ecb4a2c6f1ac5cc9b394dc64d3bb14ca650c4f60
@@ -79,7 +79,7 @@ F src/vdbe.c b324acdaff3b1f21cd369bbb0df30e1c3fa828f4
 F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
 F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
 F src/vdbeapi.c 3965bf4678ae32c05f73550c1b5be3268f9f3006
-F src/vdbeaux.c 544ff66308d3184b519decc731abb65c5233bc2d
+F src/vdbeaux.c c6da55e0096e141211f918837eca98e0be6400b4
 F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
 F src/where.c 6e637a6b3e61fe3104adc4e5caa4738bf6570daa
 F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
@@ -252,7 +252,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
-P b9d5f007fc32d4f471e0e11cc4baadb100612878
-R 18a567bb56395dc74db3aa4daaced6ab
-U danielk1977
-Z 17328cbcaecb7be2165f3f20c069642c
+P cfee7f4a004c5e57d58edcf9de3ded0a199940a3
+R ec15467724d6da43213b204975fda018
+U drh
+Z 4e4b37ba057c6cd50535fae2a97094d4
index 0978fc9774e6b4e6c17c7706cf117d00504bc229..f3fad82afe30b2f23c793bd285e419752dab9f25 100644 (file)
@@ -1 +1 @@
-cfee7f4a004c5e57d58edcf9de3ded0a199940a3
\ No newline at end of file
+b0506bdd701339d63166ada065445776dd499588
\ No newline at end of file
index 1a30b0101c9f85005373cd48904f29e20e6ca8bf..5d9f9c0e86757aa8dbf556712d99ca5862f6c3a2 100644 (file)
@@ -24,9 +24,9 @@
 **     PRAGMA
 **
 <<<<<<< build.c
-** $Id: build.c,v 1.267 2004/11/05 09:19:28 danielk1977 Exp $
+** $Id: build.c,v 1.268 2004/11/05 17:17:50 drh Exp $
 =======
-** $Id: build.c,v 1.267 2004/11/05 09:19:28 danielk1977 Exp $
+** $Id: build.c,v 1.268 2004/11/05 17:17:50 drh Exp $
 >>>>>>> 1.262
 */
 #include "sqliteInt.h"
@@ -719,6 +719,17 @@ void sqlite3StartTable(
   if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable);
   pParse->pNewTable = pTable;
 
+  /* If this is the magic sqlite_sequence table used by autoincrement,
+  ** then record a pointer to this table in the main database structure
+  ** so that INSERT can find the table easily.
+  */
+#ifndef SQLITE_OMIT_AUTOINCREMENT
+  if( strcmp(zName, "sqlite_sequence")==0 ){
+    assert( db->aDb[iDb].pSeqTab==0 );
+    db->aDb[iDb].pSeqTab = pTable;
+  }
+#endif
+
   /* Begin generating the code that will insert the table record into
   ** the SQLITE_MASTER table.  Note in particular that we must go ahead
   ** and allocate the record number for the table entry now.  Before any
@@ -738,6 +749,10 @@ void sqlite3StartTable(
     sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
     sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
 
+    /* This just creates a place-holder record in the sqlite_master table.
+    ** The record created does not contain anything yet.  It will be replaced
+    ** by the real entry in code generated at sqlite3EndTable().
+    */
     sqlite3OpenMasterTable(v, iDb);
     sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
     sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
@@ -913,8 +928,10 @@ void sqlite3AddPrimaryKey(
     pTab->keyConf = onError;
     pTab->autoInc = autoInc;
   }else if( autoInc ){
+#ifndef SQLITE_OMIT_AUTOINCREMENT
     sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
        "INTEGER PRIMARY KEY");
+#endif
   }else{
     sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0);
     pList = 0;
@@ -1350,16 +1367,27 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
   if( !db->init.busy ){
     int n;
     Vdbe *v;
+    char *zType;    /* "view" or "table" */
+    char *zType2;   /* "VIEW" or "TABLE" */
+    char *zStmt;    /* Text of the CREATE TABLE or CREATE VIEW statement */
 
     v = sqlite3GetVdbe(pParse);
     if( v==0 ) return;
 
+    /* Create the rootpage for the new table and push it onto the stack.
+    ** A view has no rootpage, so just push a zero onto the stack for
+    ** views.  Initialize zType at the same time.
+    */
     if( p->pSelect==0 ){
       /* A regular table */
       sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0);
+      zType = "table";
+      zType2 = "TABLE";
     }else{
       /* A view */
       sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
+      zType = "view";
+      zType2 = "VIEW";
     }
 
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
@@ -1391,7 +1419,8 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
         sqlite3DeleteTable(0, pSelTab);
       }
     }
-  
+
+#if 0  
     sqlite3OpenMasterTable(v, p->iDb);
 
     sqlite3VdbeOp3(v, OP_String8, 0, 0, p->pSelect==0?"table":"view",P3_STATIC);
@@ -1421,6 +1450,36 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
     sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
     sqlite3ChangeCookie(db, v, p->iDb);
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
+#endif
+
+    /* Compute the complete text of the CREATE statement */
+    if( pSelect ){
+      zStmt = createTableStmt(p);
+    }else{
+      n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1;
+      zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z);
+    }
+
+    /* A slot for the record has already been allocated in the 
+    ** SQLITE_MASTER table.  We just need to update that slot with all
+    ** the information we've collected.  The rowid for the preallocated
+    ** slot is the 2nd item on the stack.  The top of the stack is the
+    ** root page for the new table (or a 0 if this is a view).
+    */
+    sqlite3NestedParse(pParse,
+      "UPDATE %Q.%s "
+         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q "
+       "WHERE rowid=#1",
+      db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb),
+      zType,
+      p->zName,
+      p->zName,
+      zStmt
+    );
+    sqliteFree(zStmt);
+
+    /* Reparse everything to update our internal data structures */
+    sqlite3ChangeCookie(db, v, p->iDb);
     sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
         sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
   }
@@ -1648,7 +1707,7 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
   ** is on the top of the stack.  See sqlite3RegisterExpr().
   */
   sqlite3NestedParse(pParse, 
-     "UPDATE %Q.%Q SET rootpage=%d WHERE #0 AND rootpage=#0",
+     "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0",
      pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable);
 #endif
 }
@@ -1793,7 +1852,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
     ** database.
     */
     sqlite3NestedParse(pParse, 
-        "DELETE FROM %Q.%Q WHERE tbl_name=%Q and type!='trigger'",
+        "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
         db->aDb[pTab->iDb].zName, SCHEMA_TABLE(pTab->iDb), pTab->zName);
     if( !isView ){
       destroyTable(pParse, pTab);
index da140c58f4dd9a8f45927216fe51bb3ef4611c5b..0ed2a7d175c21ae0ebaba9ae61dbd13b87be414f 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle DELETE FROM statements.
 **
-** $Id: delete.c,v 1.87 2004/11/05 06:02:07 danielk1977 Exp $
+** $Id: delete.c,v 1.88 2004/11/05 17:17:50 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -170,7 +170,7 @@ void sqlite3DeleteFrom(
   if( v==0 ){
     goto delete_from_cleanup;
   }
-  sqlite3VdbeCountChanges(v);
+  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
   sqlite3BeginWriteOperation(pParse, row_triggers_exist, pTab->iDb);
 
   /* If we are trying to delete from a view, construct that view into
@@ -295,7 +295,7 @@ void sqlite3DeleteFrom(
       }
 
       /* Delete the row */
-      sqlite3GenerateRowDelete(db, v, pTab, iCur, 1);
+      sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);
     }
 
     /* If there are row triggers, close all cursors then invoke
index e061b590ab3c97e1a1f29d776de7f08cc9e58683..887d5f1df19015defac21fc7ccc62614143bd574 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.122 2004/11/05 06:02:07 danielk1977 Exp $
+** $Id: insert.c,v 1.123 2004/11/05 17:17:50 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -262,7 +262,7 @@ void sqlite3Insert(
   */
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) goto insert_cleanup;
-  sqlite3VdbeCountChanges(v);
+  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
   sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb);
 
   /* if there are row triggers, allocate a temp table for new.* references. */
@@ -999,7 +999,11 @@ void sqlite3CompleteInsertion(
     sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
     sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
   }
-  pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
+  if( pParse->nested ){
+    pik_flags = 0;
+  }else{
+    pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
+  }
   sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags);
   
   if( isUpdate && recnoChng ){
index 43e12863721072cb31f498e050a187dd0a884921..6e700771b4ba2e34ef6129d67a1748abc47bde2d 100644 (file)
@@ -99,6 +99,7 @@ typedef struct et_info {   /* Information about each format field */
 */
 #define FLAG_SIGNED  1     /* True if the value to convert is signed */
 #define FLAG_INTERN  2     /* True if for internal use only */
+#define FLAG_STRING  4     /* Allow infinity precision */
 
 
 /*
@@ -109,10 +110,10 @@ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
 static const char aPrefix[] = "-x0\000X0";
 static const et_info fmtinfo[] = {
   {  'd', 10, 1, etRADIX,      0,  0 },
-  {  's',  0, 0, etSTRING,     0,  0 },
-  {  'z',  0, 2, etDYNSTRING,  0,  0 },
-  {  'q',  0, 0, etSQLESCAPE,  0,  0 },
-  {  'Q',  0, 0, etSQLESCAPE2, 0,  0 },
+  {  's',  0, 4, etSTRING,     0,  0 },
+  {  'z',  0, 6, etDYNSTRING,  0,  0 },
+  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
+  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
   {  'c',  0, 0, etCHARX,      0,  0 },
   {  'o',  8, 0, etRADIX,      0,  2 },
   {  'u', 10, 0, etRADIX,      0,  0 },
@@ -296,8 +297,6 @@ static int vxprintf(
           c = *++fmt;
         }
       }
-      /* Limit the precision to prevent overflowing buf[] during conversion */
-      if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40;
     }else{
       precision = -1;
     }
@@ -328,6 +327,11 @@ static int vxprintf(
     }
     zExtra = 0;
 
+    /* Limit the precision to prevent overflowing buf[] during conversion */
+    if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
+      precision = etBUFSIZE-40;
+    }
+
     /*
     ** At this point, variables are initialized as follows:
     **
@@ -563,13 +567,15 @@ static int vxprintf(
       case etSQLESCAPE2:
         {
           int i, j, n, c, isnull;
+          int needQuote;
           char *arg = va_arg(ap,char*);
           isnull = arg==0;
           if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
           for(i=n=0; (c=arg[i])!=0; i++){
             if( c=='\'' )  n++;
           }
-          n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0);
+          needQuote = !isnull && xtype==etSQLESCAPE2;
+          n += i + 1 + needQuote*2;
           if( n>etBUFSIZE ){
             bufpt = zExtra = sqliteMalloc( n );
             if( bufpt==0 ) return -1;
@@ -577,12 +583,12 @@ static int vxprintf(
             bufpt = buf;
           }
           j = 0;
-          if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
+          if( needQuote ) bufpt[j++] = '\'';
           for(i=0; (c=arg[i])!=0; i++){
             bufpt[j++] = c;
             if( c=='\'' ) bufpt[j++] = c;
           }
-          if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
+          if( needQuote ) bufpt[j++] = '\'';
           bufpt[j] = 0;
           length = j;
           if( precision>=0 && precision<length ) length = precision;
index f7a51aa522fb6952afd3eb2bd02c1b9f60ed2d57..a0d8ecddcb34a7895eeabb97d50917ae7beff758 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.333 2004/11/05 05:10:29 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.334 2004/11/05 17:17:50 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -324,7 +324,8 @@ struct Db {
   u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   u8 safety_level;     /* How aggressive at synching data to disk */
   int cache_size;      /* Number of pages to use in the cache */
-  void *pAux;          /* Auxiliary data.  Usually NULL */
+  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
+  void *pAux;               /* Auxiliary data.  Usually NULL */
   void (*xFreeAux)(void*);  /* Routine to free pAux */
 };
 
index e7a340f97c1db9b6f629d2743eba2137f5773cd3..d53d86f77aca61c2ac971463926285981387100c 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.93 2004/11/05 06:02:07 danielk1977 Exp $
+** $Id: update.c,v 1.94 2004/11/05 17:17:50 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -220,7 +220,7 @@ void sqlite3Update(
   */
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) goto update_cleanup;
-  sqlite3VdbeCountChanges(v);
+  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
   sqlite3BeginWriteOperation(pParse, 1, pTab->iDb);
 
   /* If we are trying to update a view, construct that view into
index b2fad8e39a71c74e0bd15fe0049d0b172a3f7dea..44c9c3f21ff65324e3f274317ff26ec4eb93f8a7 100644 (file)
@@ -1806,6 +1806,6 @@ void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
 ** Set a flag in the vdbe to update the change counter when it is finalised
 ** or reset.
 */
-void sqlite3VdbeCountChanges(Vdbe *p){
-  p->changeCntOn = 1;
+void sqlite3VdbeCountChanges(Vdbe *v){
+  v->changeCntOn = 1;
 }