]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a segfault associated with the column cache that occurs on nested VIEWs.
authordrh <drh@noemail.net>
Mon, 8 Dec 2008 13:42:36 +0000 (13:42 +0000)
committerdrh <drh@noemail.net>
Mon, 8 Dec 2008 13:42:36 +0000 (13:42 +0000)
Ticket #3527. (CVS 5989)

FossilOrigin-Name: 490138a2012fcb4c859e1cf12a35e314ec1060d2

manifest
manifest.uuid
src/expr.c
src/sqliteInt.h
test/tkt3527.test [new file with mode: 0644]

index a9c13986e2cefe71d0750fdd6897f1aaed9e0889..41177182b592dea7848985eb39ce43129f6838c7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Make\ssure\sa\smemory\sallocation\serror\sdid\snot\sprevent\sUTF16\sto\sUTF8\sconversion\nprior\sto\sdoing\sa\sstring\scomparison.\s(CVS\s5988)
-D 2008-12-06T16:46:14
+C Fix\sa\ssegfault\sassociated\swith\sthe\scolumn\scache\sthat\soccurs\son\snested\sVIEWs.\nTicket\s#3527.\s(CVS\s5989)
+D 2008-12-08T13:42:36
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in f7e4c81c347b04f7b0f1c1b081a168645d7b8af7
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -108,7 +108,7 @@ F src/callback.c e970e5beddbdb23f89a6d05cb1a6419d9f755624
 F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
 F src/date.c 88898ae96a0d7f66711caffa40b2cf30e623a387
 F src/delete.c d60885716666e5ea0f177b8db73c22c67ccba2cb
-F src/expr.c 9ce4f2585325bf3550d24fe60883a87263e0f630
+F src/expr.c ee295129a9efa0466ae4ebdb03adc33cd5c2e184
 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
 F src/func.c b4570eb73d873041b8e68f5cdbb4556ff13a94c3
 F src/global.c 20a3fe46c8287a01ba3a7442558f0eb70c66b19a
@@ -155,7 +155,7 @@ F src/select.c 1d3616e4e48f6c15a0c69bf14bc5423f31624f87
 F src/shell.c be9eeb5811d1ad6ebbf6ae8b5aa04ae1368af033
 F src/sqlite.h.in b5d50f12fb9c7460a4ddfef8c1e799afaabefebf
 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
-F src/sqliteInt.h 391992f5bd54560758c618f7b858c1c4ea060883
+F src/sqliteInt.h 93d6ef19eb949aced1ae32338f3262304596fee8
 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
 F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
@@ -583,6 +583,7 @@ F test/tkt3472.test 98c7e54b8fef2b1266a552a66c8e5d88a6908d1d
 F test/tkt3493.test 8472b3464e49a27ff7271308eec46154209e667b
 F test/tkt3508.test d9e285ff91731247d4673f9252fe5934639d7f0d
 F test/tkt3522.test 22ce2ebbcb04a6be56c0977d405c207967318fd6
+F test/tkt3527.test ee4af96183579565987e58873a7490bc04934ffb
 F test/tkt35xx.test 53bca895091e968126a858ee7da186f59f328994
 F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
 F test/trace.test 951cd0f5f571e7f36bf7bfe04be70f90fb16fb00
@@ -663,7 +664,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 76246d9f0d4e995f6be6fbd1fa2bcabc1b9566ae
-R 44bbf1bea4319f9b234d44baa1ddfaa7
+P 9d061e20d885bee7ac7875500a0e7c238b540a63
+R 0e9bcc610555d728a81eaf83a45e7f41
 U drh
-Z 4c6e9127786c5b554c8b62926c58464b
+Z 3a9348ac11f48ee17609e92ff5312be5
index ac432fdb6866c39f42d409caf80db5df163b01ba..c437cf3ac7245aa3d338064f9e9fb2ef898d473d 100644 (file)
@@ -1 +1 @@
-9d061e20d885bee7ac7875500a0e7c238b540a63
\ No newline at end of file
+490138a2012fcb4c859e1cf12a35e314ec1060d2
\ No newline at end of file
index 0796c8dba4bff19594877743a4b4c80d5c9ea98d..10db73964dd4d7d23142edbe328ff26f76bd3248 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.405 2008/12/05 15:24:17 drh Exp $
+** $Id: expr.c,v 1.406 2008/12/08 13:42:36 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1725,10 +1725,14 @@ void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){
 static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr, int target){
   sqlite3 *db = pParse->db;
   int iReg;
-  if( pParse->aAlias==0 ){
-    pParse->aAlias = sqlite3DbMallocZero(db, 
+  if( pParse->nAliasAlloc<pParse->nAlias ){
+    pParse->aAlias = sqlite3DbReallocOrFree(db, pParse->aAlias,
                                  sizeof(pParse->aAlias[0])*pParse->nAlias );
+    testcase( db->mallocFailed && pParse->nAliasAlloc>0 );
     if( db->mallocFailed ) return 0;
+    memset(&pParse->aAlias[pParse->nAliasAlloc], 0,
+           (pParse->nAlias-pParse->nAliasAlloc)*sizeof(pParse->aAlias[0]));
+    pParse->nAliasAlloc = pParse->nAlias;
   }
   assert( iAlias>0 && iAlias<=pParse->nAlias );
   iReg = pParse->aAlias[iAlias-1];
index 5758aa4078335cd2be42e1defc05b1a684a05c09..adf051033a5f88fe2e0d46f4bd1bf25663a0f4d9 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.802 2008/12/05 17:17:08 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.803 2008/12/08 13:42:36 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1752,6 +1752,7 @@ struct Parse {
   int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
   Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
   int nAlias;          /* Number of aliased result set columns */
+  int nAliasAlloc;     /* Number of allocated slots for aAlias[] */
   int *aAlias;         /* Register used to hold aliased result */
   u8 explain;          /* True if the EXPLAIN flag is found on the query */
   Token sErrToken;     /* The token at which the error occurred */
diff --git a/test/tkt3527.test b/test/tkt3527.test
new file mode 100644 (file)
index 0000000..34e9e61
--- /dev/null
@@ -0,0 +1,118 @@
+# 2008 December 8
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+#
+# This file is a verification that the bugs identified in ticket
+# #3527 have been fixed.
+#
+# $Id: tkt3527.test,v 1.1 2008/12/08 13:42:36 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_test tkt3527-1.1 {
+  db eval {
+    CREATE TABLE Element (
+     Code INTEGER PRIMARY KEY,
+     Name VARCHAR(60)
+    );
+    
+    CREATE TABLE ElemOr (
+     CodeOr INTEGER NOT NULL,
+     Code INTEGER NOT NULL,
+     PRIMARY KEY(CodeOr,Code)
+    );
+    
+    CREATE TABLE ElemAnd (
+     CodeAnd INTEGER,
+     Code INTEGER,
+     Attr1 INTEGER,
+     Attr2 INTEGER,
+     Attr3 INTEGER,
+     PRIMARY KEY(CodeAnd,Code)
+    );
+    
+    INSERT INTO Element VALUES(1,'Elem1');
+    INSERT INTO Element VALUES(2,'Elem2');
+    INSERT INTO Element VALUES(3,'Elem3');
+    INSERT INTO Element VALUES(4,'Elem4');
+    INSERT INTO Element VALUES(5,'Elem5');
+    INSERT INTO ElemOr Values(3,4);
+    INSERT INTO ElemOr Values(3,5);
+    INSERT INTO ElemAnd VALUES(1,3,1,1,1);
+    INSERT INTO ElemAnd VALUES(1,2,1,1,1);
+    
+    CREATE VIEW ElemView1 AS
+    SELECT
+      CAST(Element.Code AS VARCHAR(50)) AS ElemId,
+     Element.Code AS ElemCode,
+     Element.Name AS ElemName,
+     ElemAnd.Code AS InnerCode,
+     ElemAnd.Attr1 AS Attr1,
+     ElemAnd.Attr2 AS Attr2,
+     ElemAnd.Attr3 AS Attr3,
+     0 AS Level,
+     0 AS IsOrElem
+    FROM Element JOIN ElemAnd ON ElemAnd.CodeAnd=Element.Code
+    WHERE ElemAnd.CodeAnd NOT IN (SELECT CodeOr FROM ElemOr)
+    UNION ALL
+    SELECT
+      CAST(ElemOr.CodeOr AS VARCHAR(50)) AS ElemId,
+      Element.Code AS ElemCode,
+      Element.Name AS ElemName,
+      ElemOr.Code AS InnerCode,
+      NULL AS Attr1,
+      NULL AS Attr2,
+      NULL AS Attr3,
+      0 AS Level,
+      1 AS IsOrElem
+    FROM ElemOr JOIN Element ON Element.Code=ElemOr.CodeOr
+    ORDER BY ElemId, InnerCode;
+    
+    CREATE VIEW ElemView2 AS
+    SELECT
+      ElemId,
+      ElemCode,
+      ElemName,
+      InnerCode,
+      Attr1,
+      Attr2,
+      Attr3,
+      Level,
+      IsOrElem
+    FROM ElemView1
+    UNION ALL
+    SELECT
+      Element.ElemId || '.' || InnerElem.ElemId AS ElemId,
+      InnerElem.ElemCode,
+      InnerElem.ElemName,
+      InnerElem.InnerCode,
+      InnerElem.Attr1,
+      InnerElem.Attr2,
+      InnerElem.Attr3,
+      InnerElem.Level+1,
+      InnerElem.IsOrElem
+    FROM ElemView1 AS Element
+    JOIN ElemView1 AS InnerElem
+         ON Element.Level=0 AND Element.InnerCode=InnerElem.ElemCode
+    ORDER BY ElemId, InnerCode;
+    SELECT * FROM ElemView1;
+  }
+} {1 1 Elem1 2 1 1 1 0 0 1 1 Elem1 3 1 1 1 0 0 3 3 Elem3 4 {} {} {} 0 1 3 3 Elem3 5 {} {} {} 0 1}
+   
+do_test tkt3527-1.2 {
+  db eval {
+    SELECT * FROM ElemView2;
+  }
+} {1 1 Elem1 2 1 1 1 0 0 1 1 Elem1 3 1 1 1 0 0 1.3 3 Elem3 4 {} {} {} 1 1 1.3 3 Elem3 5 {} {} {} 1 1 3 3 Elem3 4 {} {} {} 0 1 3 3 Elem3 5 {} {} {} 0 1}
+
+finish_test