Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a segfault associated with the column cache that occurs on nested VIEWs. Ticket #3527. (CVS 5989) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
490138a2012fcb4c859e1cf12a35e314 |
User & Date: | drh 2008-12-08 13:42:36.000 |
Context
2008-12-08
| ||
16:01 | Fix two unused-parameter warnings in the parser. (CVS 5990) (check-in: cf419d0b01 user: drh tags: trunk) | |
13:42 | Fix a segfault associated with the column cache that occurs on nested VIEWs. Ticket #3527. (CVS 5989) (check-in: 490138a201 user: drh tags: trunk) | |
2008-12-06
| ||
16:46 | Make sure a memory allocation error did not prevent UTF16 to UTF8 conversion prior to doing a string comparison. (CVS 5988) (check-in: 9d061e20d8 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.406 2008/12/08 13:42:36 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
1721 1722 1723 1724 1725 1726 1727 | ** pParse->aAlias[iAlias-1] records the register number where the value ** of the iAlias-th alias is stored. If zero, that means that the ** alias has not yet been computed. */ static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr, int target){ sqlite3 *db = pParse->db; int iReg; | | | > > > > | 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 | ** pParse->aAlias[iAlias-1] records the register number where the value ** of the iAlias-th alias is stored. If zero, that means that the ** alias has not yet been computed. */ static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr, int target){ sqlite3 *db = pParse->db; int iReg; 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]; if( iReg==0 ){ if( pParse->disableColCache ){ iReg = sqlite3ExprCodeTarget(pParse, pExpr, target); }else{ |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.803 2008/12/08 13:42:36 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 | ** each recursion */ int nVar; /* Number of '?' variables seen in the SQL so far */ int nVarExpr; /* Number of used slots in apVarExpr[] */ 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 *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 */ Token sNameToken; /* Token with unqualified schema object name */ Token sLastToken; /* The last token parsed */ const char *zSql; /* All SQL text */ const char *zTail; /* All SQL text past the last semicolon parsed */ | > | 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 | ** each recursion */ int nVar; /* Number of '?' variables seen in the SQL so far */ int nVarExpr; /* Number of used slots in apVarExpr[] */ 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 */ Token sNameToken; /* Token with unqualified schema object name */ Token sLastToken; /* The last token parsed */ const char *zSql; /* All SQL text */ const char *zTail; /* All SQL text past the last semicolon parsed */ |
︙ | ︙ |
Added test/tkt3527.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 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 |