]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The {quote: SrcList} object was not being expanded correctly by a call to
authordrh <drh@noemail.net>
Wed, 30 Jul 2003 12:34:12 +0000 (12:34 +0000)
committerdrh <drh@noemail.net>
Wed, 30 Jul 2003 12:34:12 +0000 (12:34 +0000)
sqliteSrcListAppend() if the {quote: SrcList} had previously been duplicated by
a call to sqliteSrcListDup().  Ticket #416. This check-in fixes that problem
by keeping a separate nAlloc field on {quote: SrcList}.  A similar change is made
to {quote: IdList} and {quote: ExprList} to avoid future problems. (CVS 1067)

FossilOrigin-Name: da6273255471673841fdcadc688aeac80722e130

manifest
manifest.uuid
src/build.c
src/expr.c
src/sqliteInt.h
src/util.c
test/misc2.test

index 93d8d9072365ee4545ee672b342385c08145aec6..65e7fbdc58f010f8d0e19710427d56b43faf0411 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C When\screating\sa\snew\sjournal\sfile,\sopen\sa\s(read-only)\sfile\sdescriptor\son\sthe\ndirectory\scontaining\sthe\sjournal\sand\ssync\sthat\sdirectory\sonce\sto\smake\ssure\nthat\sthe\sjournal\sfilename\sentry\sgets\sinto\sthe\sdirectory.\s\sTicket\s#410.\s(CVS\s1066)
-D 2003-07-27T18:59:43
+C The\s{quote:\sSrcList}\sobject\swas\snot\sbeing\sexpanded\scorrectly\sby\sa\scall\sto\r\nsqliteSrcListAppend()\sif\sthe\s{quote:\sSrcList}\shad\spreviously\sbeen\sduplicated\sby\r\na\scall\sto\ssqliteSrcListDup().\s\sTicket\s#416.\sThis\scheck-in\sfixes\sthat\sproblem\r\nby\skeeping\sa\sseparate\snAlloc\sfield\son\s{quote:\sSrcList}.\s\sA\ssimilar\schange\sis\smade\r\nto\s{quote:\sIdList}\sand\s{quote:\sExprList}\sto\savoid\sfuture\sproblems.\s(CVS\s1067)
+D 2003-07-30T12:34:12
 F Makefile.in 9ad23ed4ca97f9670c4496432e3fbd4b3760ebde
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -24,11 +24,11 @@ F src/auth.c c8f50d4507e37779d96ff3c55417bc2b612dfed6
 F src/btree.c ba1cc0c71c3d2742b9a9047832335dc7d3656c45
 F src/btree.h 9b7c09f1e64274d7bb74a57bbfc63778f67b1048
 F src/btree_rb.c f30f5cddc4375c05bf361116da1492d9601760ca
-F src/build.c 13b6ae48ce71a0f59368f548dba2a662375aeaf6
+F src/build.c 335a4db960a3305e16c64d67726dd534386df7c3
 F src/copy.c 9e47975ea96751c658bcf1a0c4f0bb7c6ee61e73
 F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc
 F src/encode.c 25ea901a9cefb3d93774afa4a06b57cb58acf544
-F src/expr.c 3c07e7b5374649c4921b4ff1287f57d513876c3f
+F src/expr.c 03c321ac66c1e998c2e0faf22184b5a808b559ca
 F src/func.c 6b23578d48a8be98a664db145a635c2fa9ddb57b
 F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3
 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
@@ -47,7 +47,7 @@ F src/select.c 2fa83d6c972d3e3f379faee32e3621411490dedb
 F src/shell.c c2ba26c850874964f5ec1ebf6c43406f28e44c4a
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in dafa83571810b6932f089b589c783355ef7a54b5
-F src/sqliteInt.h e3c756e5aa7bcbf7fbcd20e6aef640c9359c23f2
+F src/sqliteInt.h a57cafea9ef34e73e4504ada4bc70417def67f1e
 F src/table.c 4301926464d88d2c2c7cd21c3360aa75bf068b95
 F src/tclsqlite.c d6860dcd56348b9521726280b72c412d2a33ae97
 F src/test1.c b12b585bfb4763df3262975ed8d3f4f274b5eaed
@@ -57,7 +57,7 @@ F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
 F src/tokenize.c 2ba93fe10d5f57f0cc20b07417c3244a30c324b3
 F src/trigger.c 6ff205aaac4869e402d9902e528e1d22a85de14c
 F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
-F src/util.c 566c7780170dd11fb1ad5de3ba81f0dfea7cccf0
+F src/util.c 9ab0f573d31ad8c3cf1fcb6bef7a6299e09463fa
 F src/vacuum.c 0820984615786c9ccdaad8032a792309b354a8eb
 F src/vdbe.c 779fa3b15148161282a71241ff9733a54a8b0648
 F src/vdbe.h d853ed6cc4727fa9e8ace6187c55afcf817041dd
@@ -97,7 +97,7 @@ F test/memdb.test cd4580f466f34c42354612a375c5adb90447e4c4
 F test/memleak.test a18e6810cae96d2f6f5136920267adbefc8e1e90
 F test/minmax.test 6d9b6d6ee34f42e2a58dffece1f76d35f446b3af
 F test/misc1.test c7dc2f2bd702d8283e885a64ec0714be26cfb051
-F test/misc2.test d8a0b59399a53fd27e74a8fac2a22d5271b9bded
+F test/misc2.test 6400032fe041360f717f501930585498853d79ae
 F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
 F test/null.test 5c2b57307e4b6178aae825eb65ddbee01e76b0fd
@@ -168,7 +168,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3
 F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
-P 8c163fc0c7c721b7a5fa6727b0e90bff4484c782
-R 8fa888001788f8c7b2a2f5a0b6144c1c
+P 09c10fe3c99cffc64ed02c2929f206d99c8e3309
+R d2bc63b0694faef8c02f9403066fd889
 U drh
-Z 5beb2c4636d8c2b6025132999d440be1
+Z 6699c88f8cb611bb62eca292eb62c177
index da11a898856f622f9a72de460c35d27cfa7f0846..744565273da93e5954168a0b767946846f3e9d68 100644 (file)
@@ -1 +1 @@
-09c10fe3c99cffc64ed02c2929f206d99c8e3309
\ No newline at end of file
+da6273255471673841fdcadc688aeac80722e130
\ No newline at end of file
index f92369f23be4882e950baa52beb1287fd1a447b3..07143576186188b1216d6187b5c841b415bf29ab 100644 (file)
@@ -23,7 +23,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.156 2003/07/01 18:13:15 drh Exp $
+** $Id: build.c,v 1.157 2003/07/30 12:34:12 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1911,10 +1911,12 @@ IdList *sqliteIdListAppend(IdList *pList, Token *pToken){
   if( pList==0 ){
     pList = sqliteMalloc( sizeof(IdList) );
     if( pList==0 ) return 0;
+    pList->nAlloc = 0;
   }
-  if( (pList->nId & 7)==0 ){
+  if( pList->nId>=pList->nAlloc ){
     struct IdList_item *a;
-    a = sqliteRealloc(pList->a, (pList->nId+8)*sizeof(pList->a[0]) );
+    pList->nAlloc = pList->nAlloc*2 + 5;
+    a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) );
     if( a==0 ){
       sqliteIdListDelete(pList);
       return 0;
@@ -1965,11 +1967,13 @@ SrcList *sqliteSrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){
   if( pList==0 ){
     pList = sqliteMalloc( sizeof(SrcList) );
     if( pList==0 ) return 0;
+    pList->nAlloc = 1;
   }
-  if( (pList->nSrc & 7)==1 ){
+  if( pList->nSrc>=pList->nAlloc ){
     SrcList *pNew;
+    pList->nAlloc *= 2;
     pNew = sqliteRealloc(pList,
-               sizeof(*pList) + (pList->nSrc+8)*sizeof(pList->a[0]) );
+               sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) );
     if( pNew==0 ){
       sqliteSrcListDelete(pList);
       return 0;
index 7f3f96f603dd8684536c0aa933285ccae2bdebc5..804e751b798ec2c57d68267d73e9aff9622f12fe 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.97 2003/07/20 01:16:47 drh Exp $
+** $Id: expr.c,v 1.98 2003/07/30 12:34:12 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -160,7 +160,7 @@ ExprList *sqliteExprListDup(ExprList *p){
   if( p==0 ) return 0;
   pNew = sqliteMalloc( sizeof(*pNew) );
   if( pNew==0 ) return 0;
-  pNew->nExpr = p->nExpr;
+  pNew->nExpr = pNew->nAlloc = p->nExpr;
   pNew->a = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
   if( pNew->a==0 ) return 0;
   for(i=0; i<p->nExpr; i++){
@@ -189,7 +189,7 @@ SrcList *sqliteSrcListDup(SrcList *p){
   nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
   pNew = sqliteMalloc( nByte );
   if( pNew==0 ) return 0;
-  pNew->nSrc = p->nSrc;
+  pNew->nSrc = pNew->nAlloc = p->nSrc;
   for(i=0; i<p->nSrc; i++){
     pNew->a[i].zDatabase = sqliteStrDup(p->a[i].zDatabase);
     pNew->a[i].zName = sqliteStrDup(p->a[i].zName);
@@ -209,7 +209,7 @@ IdList *sqliteIdListDup(IdList *p){
   if( p==0 ) return 0;
   pNew = sqliteMalloc( sizeof(*pNew) );
   if( pNew==0 ) return 0;
-  pNew->nId = p->nId;
+  pNew->nId = pNew->nAlloc = p->nId;
   pNew->a = sqliteMalloc( p->nId*sizeof(p->a[0]) );
   if( pNew->a==0 ) return 0;
   for(i=0; i<p->nId; i++){
@@ -253,11 +253,12 @@ ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
       sqliteExprDelete(pExpr);
       return 0;
     }
+    pList->nAlloc = 0;
   }
-  if( (pList->nExpr & 7)==0 ){
-    int n = pList->nExpr + 8;
+  if( pList->nAlloc<=pList->nExpr ){
     struct ExprList_item *a;
-    a = sqliteRealloc(pList->a, n*sizeof(pList->a[0]));
+    pList->nAlloc = pList->nAlloc*2 + 4;
+    a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]));
     if( a==0 ){
       sqliteExprDelete(pExpr);
       return pList;
index 465f6af48c8475971952922afe36fb5328fb9786..63604d9ea1ff31990f979b8ce6351c3ced9da403 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.194 2003/07/20 01:16:47 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.195 2003/07/30 12:34:12 drh Exp $
 */
 #include "config.h"
 #include "sqlite.h"
@@ -653,6 +653,7 @@ struct Expr {
 */
 struct ExprList {
   int nExpr;             /* Number of expressions on the list */
+  int nAlloc;            /* Number of entries allocated below */
   struct ExprList_item {
     Expr *pExpr;           /* The list of expressions */
     char *zName;           /* Token associated with this expression */
@@ -679,6 +680,7 @@ struct ExprList {
 */
 struct IdList {
   int nId;         /* Number of identifiers on the list */
+  int nAlloc;      /* Number of entries allocated for a[] below */
   struct IdList_item {
     char *zName;      /* Name of the identifier */
     int idx;          /* Index in some Table.aCol[] of a column named zName */
@@ -697,7 +699,8 @@ struct IdList {
 ** now be identified by a database name, a dot, then the table name: ID.ID.
 */
 struct SrcList {
-  int nSrc;        /* Number of tables or subqueries in the FROM clause */
+  u16 nSrc;        /* Number of tables or subqueries in the FROM clause */
+  u16 nAlloc;      /* Number of entries allocated in a[] below */
   struct SrcList_item {
     char *zDatabase;  /* Name of database holding this table */
     char *zName;      /* Name of the table */
index be5baa59c25ffc0ab95d66d9f5700fb741990b91..fcced7e611620f007762753152c999dae2f5e08f 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.65 2003/06/05 14:27:56 drh Exp $
+** $Id: util.c,v 1.66 2003/07/30 12:34:12 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -43,6 +43,10 @@ int sqlite_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
 static int memcnt = 0;
 #endif
 
+/*
+** Number of 32-bit guard words
+*/
+#define N_GUARD 1
 
 /*
 ** Allocate new memory and set it to zero.  Return NULL if
@@ -51,7 +55,7 @@ static int memcnt = 0;
 void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
   void *p;
   int *pi;
-  int k;
+  int i, k;
   if( sqlite_iMallocFail>=0 ){
     sqlite_iMallocFail--;
     if( sqlite_iMallocFail==0 ){
@@ -66,16 +70,16 @@ void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
   }
   if( n==0 ) return 0;
   k = (n+sizeof(int)-1)/sizeof(int);
-  pi = malloc( (3+k)*sizeof(int));
+  pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
   if( pi==0 ){
     sqlite_malloc_failed++;
     return 0;
   }
   sqlite_nMalloc++;
-  pi[0] = 0xdead1122;
-  pi[1] = n;
-  pi[k+2] = 0xdead3344;
-  p = &pi[2];
+  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
+  pi[N_GUARD] = n;
+  for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;
+  p = &pi[N_GUARD+1];
   memset(p, bZero==0, n);
 #if MEMORY_DEBUG>1
   fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",
@@ -93,13 +97,17 @@ void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
 */
 void sqliteCheckMemory(void *p, int N){
   int *pi = p;
-  int n, k;
-  pi -= 2;
-  assert( pi[0]==0xdead1122 );
-  n = pi[1];
+  int n, i, k;
+  pi -= N_GUARD+1;
+  for(i=0; i<N_GUARD; i++){
+    assert( pi[i]==0xdead1122 );
+  }
+  n = pi[N_GUARD];
   assert( N>=0 && N<n );
   k = (n+sizeof(int)-1)/sizeof(int);
-  assert( pi[k+2]==0xdead3344 );
+  for(i=0; i<N_GUARD; i++){
+    assert( pi[k+N_GUARD+1+i]==0xdead3344 );
+  }
 }
 
 /*
@@ -107,21 +115,25 @@ void sqliteCheckMemory(void *p, int N){
 */
 void sqliteFree_(void *p, char *zFile, int line){
   if( p ){
-    int *pi, k, n;
+    int *pi, i, k, n;
     pi = p;
-    pi -= 2;
+    pi -= N_GUARD+1;
     sqlite_nFree++;
-    if( pi[0]!=0xdead1122 ){
-      fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
-      return;
+    for(i=0; i<N_GUARD; i++){
+      if( pi[i]!=0xdead1122 ){
+        fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
+        return;
+      }
     }
-    n = pi[1];
+    n = pi[N_GUARD];
     k = (n+sizeof(int)-1)/sizeof(int);
-    if( pi[k+2]!=0xdead3344 ){
-      fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
-      return;
+    for(i=0; i<N_GUARD; i++){
+      if( pi[k+N_GUARD+1+i]!=0xdead3344 ){
+        fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
+        return;
+      }
     }
-    memset(pi, 0xff, (k+3)*sizeof(int));
+    memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));
 #if MEMORY_DEBUG>1
     fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",
          ++memcnt, n, (int)p, zFile,line);
@@ -136,7 +148,7 @@ void sqliteFree_(void *p, char *zFile, int line){
 ** works just like sqliteFree().
 */
 void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
-  int *oldPi, *pi, k, oldN, oldK;
+  int *oldPi, *pi, i, k, oldN, oldK;
   void *p;
   if( oldP==0 ){
     return sqliteMalloc_(n,1,zFile,line);
@@ -146,32 +158,34 @@ void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
     return 0;
   }
   oldPi = oldP;
-  oldPi -= 2;
+  oldPi -= N_GUARD+1;
   if( oldPi[0]!=0xdead1122 ){
     fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)p);
     return 0;
   }
-  oldN = oldPi[1];
+  oldN = oldPi[N_GUARD];
   oldK = (oldN+sizeof(int)-1)/sizeof(int);
-  if( oldPi[oldK+2]!=0xdead3344 ){
-    fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n", (int)p);
-    return 0;
+  for(i=0; i<N_GUARD; i++){
+    if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){
+      fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n", (int)p);
+      return 0;
+    }
   }
   k = (n + sizeof(int) - 1)/sizeof(int);
-  pi = malloc( (k+3)*sizeof(int) );
+  pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
   if( pi==0 ){
     sqlite_malloc_failed++;
     return 0;
   }
-  pi[0] = 0xdead1122;
-  pi[1] = n;
-  pi[k+2] = 0xdead3344;
-  p = &pi[2];
+  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
+  pi[N_GUARD] = n;
+  for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;
+  p = &pi[N_GUARD+1];
   memcpy(p, oldP, n>oldN ? oldN : n);
   if( n>oldN ){
     memset(&((char*)p)[oldN], 0, n-oldN);
   }
-  memset(oldPi, 0xab, (oldK+3)*sizeof(int));
+  memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));
   free(oldPi);
 #if MEMORY_DEBUG>1
   fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",
index cb2b53d86f393a4f1ab14823d9cb5decfb6b21c4..6b8994fe1969fc8a0f5d3dc1e9405863be0dbee6 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for miscellanous features that were
 # left out of other test files.
 #
-# $Id: misc2.test,v 1.5 2003/07/27 17:16:08 drh Exp $
+# $Id: misc2.test,v 1.6 2003/07/30 12:34:13 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -98,3 +98,19 @@ do_test misc2-4.6 {
     SELECT a FROM t1 WHERE a<1000000000000 ORDER BY 1;
   }
 } {1 2147483647 2147483648 4000000000}
+
+# There were some issues with expanding a SrcList object using a call
+# to sqliteSrcListAppend() if the SrcList had previously been duplicated
+# using a call to sqliteSrcListDup().  Ticket #416.  The following test
+# makes sure the problem has been fixed.
+#
+do_test misc2-5.1 {
+  execsql {
+    CREATE TABLE x(a,b);
+    CREATE VIEW y AS 
+      SELECT x1.b AS p, x2.b AS q FROM x AS x1, x AS x2 WHERE x1.a=x2.a;
+    CREATE VIEW z AS
+      SELECT y1.p, y2.p FROM y AS y1, y AS y2 WHERE y1.q=y2.q;
+    SELECT * from z;
+  }
+} {}