After calling realloc() on an array to resize it, be sure not to use pointers
into the old array. Ticket #1376. (CVS 2617) FossilOrigin-Name: 9f9a257123274779150cbc290b9f86a09b3b2c03
This commit is contained in:
parent
7681618c18
commit
9eb2028fbc
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Allow\sfloating\spoint\sliterals\sto\sbeing\sor\send\swith\sa\sdecimal\spoint.\nTicket\s#1371.\s(CVS\s2616)
|
||||
D 2005-08-23T11:31:26
|
||||
C After\scalling\srealloc()\son\san\sarray\sto\sresize\sit,\sbe\ssure\snot\sto\suse\spointers\ninto\sthe\sold\sarray.\s\sTicket\s#1376.\s(CVS\s2617)
|
||||
D 2005-08-24T03:52:19
|
||||
F Makefile.in b109ddb46a5550d0732dcd6caca01c123f6d5cdd
|
||||
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -87,7 +87,7 @@ F src/vdbeapi.c 7790e9f8da2dde29510a196d1e41ff53da7eb8a8
|
||||
F src/vdbeaux.c 874624698fad54a59c6a0bcccea9d5aaa8655ab6
|
||||
F src/vdbefifo.c b8805850afe13b43f1de78d58088cb5d66f88e1e
|
||||
F src/vdbemem.c 4732fd4d1a75dc38549493d7f9a81d02bf7c59b5
|
||||
F src/where.c 8392d521f901f83f95bf32e52255a0efe98677af
|
||||
F src/where.c 485041aa51fb33f43b346e018f7c01422847f364
|
||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
|
||||
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
|
||||
@ -233,7 +233,7 @@ F test/vacuum.test 5d4857ae2afc9c20d0edb8acc58bdc8d630126a9
|
||||
F test/vacuum2.test 5d77e98c458bcdbeecc6327de5107179ba1aa095
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/view.test ce0f0ad39fa4a3572acffcf1e634850ee151aae0
|
||||
F test/where.test b6ab0f64adc5fbb4259f284b19da6cd9aeadc711
|
||||
F test/where.test 8fcdf3e787d16d3be2d96a94d30273a98c9bbed1
|
||||
F test/where2.test 503e2e2b6abe14c5c10222e72d08ef84c1bf1ffb
|
||||
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||
F tool/lemon.c c88936c67f6411608db8fa4254d254f509fa40f6
|
||||
@ -297,7 +297,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 5cada745ac9bf18a65d21705a398b2bb8bd1aaa2
|
||||
R 23e7da0d5916b11561047a69d2280244
|
||||
P a715e7001247e84e0982335570593f0802774635
|
||||
R 6ff5e242d53c76146c4cacd607c45e12
|
||||
U drh
|
||||
Z 133248954b96d2da66ef949953aea49b
|
||||
Z 76532fdd67839f2a5a8be585f7028686
|
||||
|
@ -1 +1 @@
|
||||
a715e7001247e84e0982335570593f0802774635
|
||||
9f9a257123274779150cbc290b9f86a09b3b2c03
|
71
src/where.c
71
src/where.c
@ -16,7 +16,7 @@
|
||||
** so is applicable. Because this module is responsible for selecting
|
||||
** indices, you might also think of this module as the "query optimizer".
|
||||
**
|
||||
** $Id: where.c,v 1.164 2005/08/19 19:14:13 drh Exp $
|
||||
** $Id: where.c,v 1.165 2005/08/24 03:52:19 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -80,7 +80,6 @@ typedef struct WhereClause WhereClause;
|
||||
typedef struct WhereTerm WhereTerm;
|
||||
struct WhereTerm {
|
||||
Expr *pExpr; /* Pointer to the subexpression */
|
||||
u16 idx; /* Index of this term in pWC->a[] */
|
||||
i16 iParent; /* Disable pWC->a[iParent] when this term disabled */
|
||||
i16 leftCursor; /* Cursor number of X in "X <op> <expr>" */
|
||||
i16 leftColumn; /* Column number of X in "X <op> <expr>" */
|
||||
@ -203,9 +202,15 @@ static void whereClauseClear(WhereClause *pWC){
|
||||
/*
|
||||
** Add a new entries to the WhereClause structure. Increase the allocated
|
||||
** space as necessary.
|
||||
**
|
||||
** WARNING: This routine might reallocate the space used to store
|
||||
** WhereTerms. All pointers to WhereTerms should be invalided after
|
||||
** calling this routine. Such pointers may be reinitialized by referencing
|
||||
** the pWC->a[] array.
|
||||
*/
|
||||
static WhereTerm *whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
|
||||
static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
|
||||
WhereTerm *pTerm;
|
||||
int idx;
|
||||
if( pWC->nTerm>=pWC->nSlot ){
|
||||
WhereTerm *pOld = pWC->a;
|
||||
pWC->a = sqliteMalloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
|
||||
@ -216,14 +221,13 @@ static WhereTerm *whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
|
||||
}
|
||||
pWC->nSlot *= 2;
|
||||
}
|
||||
pTerm = &pWC->a[pWC->nTerm];
|
||||
pTerm->idx = pWC->nTerm;
|
||||
pTerm = &pWC->a[idx = pWC->nTerm];
|
||||
pWC->nTerm++;
|
||||
pTerm->pExpr = p;
|
||||
pTerm->flags = flags;
|
||||
pTerm->pWC = pWC;
|
||||
pTerm->iParent = -1;
|
||||
return pTerm;
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -438,7 +442,7 @@ static WhereTerm *findTerm(
|
||||
}
|
||||
|
||||
/* Forward reference */
|
||||
static void exprAnalyze(SrcList*, ExprMaskSet*, WhereTerm*);
|
||||
static void exprAnalyze(SrcList*, ExprMaskSet*, WhereClause*, int);
|
||||
|
||||
/*
|
||||
** Call exprAnalyze on all terms in a WHERE clause.
|
||||
@ -450,10 +454,9 @@ static void exprAnalyzeAll(
|
||||
ExprMaskSet *pMaskSet, /* table masks */
|
||||
WhereClause *pWC /* the WHERE clause to be analyzed */
|
||||
){
|
||||
WhereTerm *pTerm;
|
||||
int i;
|
||||
for(i=pWC->nTerm-1, pTerm=pWC->a; i>=0; i--, pTerm++){
|
||||
exprAnalyze(pTabList, pMaskSet, pTerm);
|
||||
for(i=pWC->nTerm-1; i>=0; i--){
|
||||
exprAnalyze(pTabList, pMaskSet, pWC, i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,8 +519,10 @@ static int isLikeOrGlob(
|
||||
static void exprAnalyze(
|
||||
SrcList *pSrc, /* the FROM clause */
|
||||
ExprMaskSet *pMaskSet, /* table masks */
|
||||
WhereTerm *pTerm /* the WHERE clause term to be analyzed */
|
||||
WhereClause *pWC, /* the WHERE clause */
|
||||
int idxTerm /* Index of the term to be analyzed */
|
||||
){
|
||||
WhereTerm *pTerm = &pWC->a[idxTerm];
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
Bitmask prereqLeft;
|
||||
Bitmask prereqAll;
|
||||
@ -545,10 +550,13 @@ static void exprAnalyze(
|
||||
WhereTerm *pNew;
|
||||
Expr *pDup;
|
||||
if( pTerm->leftCursor>=0 ){
|
||||
int idxNew;
|
||||
pDup = sqlite3ExprDup(pExpr);
|
||||
pNew = whereClauseInsert(pTerm->pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
if( pNew==0 ) return;
|
||||
pNew->iParent = pTerm->idx;
|
||||
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
if( idxNew==0 ) return;
|
||||
pNew = &pWC->a[idxNew];
|
||||
pNew->iParent = idxTerm;
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
pTerm->nChild = 1;
|
||||
pTerm->flags |= TERM_COPIED;
|
||||
}else{
|
||||
@ -577,13 +585,13 @@ static void exprAnalyze(
|
||||
assert( pList->nExpr==2 );
|
||||
for(i=0; i<2; i++){
|
||||
Expr *pNewExpr;
|
||||
WhereTerm *pNewTerm;
|
||||
int idxNew;
|
||||
pNewExpr = sqlite3Expr(ops[i], sqlite3ExprDup(pExpr->pLeft),
|
||||
sqlite3ExprDup(pList->a[i].pExpr), 0);
|
||||
pNewTerm = whereClauseInsert(pTerm->pWC, pNewExpr,
|
||||
TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
exprAnalyze(pSrc, pMaskSet, pNewTerm);
|
||||
pNewTerm->iParent = pTerm->idx;
|
||||
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
exprAnalyze(pSrc, pMaskSet, pWC, idxNew);
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
pWC->a[idxNew].iParent = idxTerm;
|
||||
}
|
||||
pTerm->nChild = 2;
|
||||
}
|
||||
@ -601,7 +609,7 @@ static void exprAnalyze(
|
||||
WhereTerm *pOrTerm;
|
||||
|
||||
assert( (pTerm->flags & TERM_DYNAMIC)==0 );
|
||||
whereClauseInit(&sOr, pTerm->pWC->pParse);
|
||||
whereClauseInit(&sOr, pWC->pParse);
|
||||
whereSplit(&sOr, pExpr, TK_OR);
|
||||
exprAnalyzeAll(pSrc, pMaskSet, &sOr);
|
||||
assert( sOr.nTerm>0 );
|
||||
@ -642,7 +650,8 @@ static void exprAnalyze(
|
||||
if( pNew ) pNew->pList = pList;
|
||||
pTerm->pExpr = pNew;
|
||||
pTerm->flags |= TERM_DYNAMIC;
|
||||
exprAnalyze(pSrc, pMaskSet, pTerm);
|
||||
exprAnalyze(pSrc, pMaskSet, pWC, idxTerm);
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
}
|
||||
or_not_possible:
|
||||
whereClauseClear(&sOr);
|
||||
@ -653,11 +662,12 @@ or_not_possible:
|
||||
/* Add constraints to reduce the search space on a LIKE or GLOB
|
||||
** operator.
|
||||
*/
|
||||
if( isLikeOrGlob(pTerm->pWC->pParse->db, pExpr, &nPattern, &isComplete) ){
|
||||
if( isLikeOrGlob(pWC->pParse->db, pExpr, &nPattern, &isComplete) ){
|
||||
Expr *pLeft, *pRight;
|
||||
Expr *pStr1, *pStr2;
|
||||
Expr *pNewExpr1, *pNewExpr2;
|
||||
WhereTerm *pNewTerm1, *pNewTerm2;
|
||||
int idxNew1, idxNew2;
|
||||
|
||||
pLeft = pExpr->pList->a[1].pExpr;
|
||||
pRight = pExpr->pList->a[0].pExpr;
|
||||
pStr1 = sqlite3Expr(TK_STRING, 0, 0, 0);
|
||||
@ -671,16 +681,15 @@ or_not_possible:
|
||||
++*(u8*)&pStr2->token.z[nPattern-1];
|
||||
}
|
||||
pNewExpr1 = sqlite3Expr(TK_GE, sqlite3ExprDup(pLeft), pStr1, 0);
|
||||
pNewTerm1 = whereClauseInsert(pTerm->pWC, pNewExpr1,
|
||||
TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
exprAnalyze(pSrc, pMaskSet, pNewTerm1);
|
||||
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
exprAnalyze(pSrc, pMaskSet, pWC, idxNew1);
|
||||
pNewExpr2 = sqlite3Expr(TK_LT, sqlite3ExprDup(pLeft), pStr2, 0);
|
||||
pNewTerm2 = whereClauseInsert(pTerm->pWC, pNewExpr2,
|
||||
TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
exprAnalyze(pSrc, pMaskSet, pNewTerm2);
|
||||
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
exprAnalyze(pSrc, pMaskSet, pWC, idxNew2);
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
if( isComplete ){
|
||||
pNewTerm2->iParent = pTerm->idx;
|
||||
pNewTerm1->iParent = pTerm->idx;
|
||||
pWC->a[idxNew1].iParent = idxTerm;
|
||||
pWC->a[idxNew2].iParent = idxTerm;
|
||||
pTerm->nChild = 2;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the use of indices in WHERE clases.
|
||||
#
|
||||
# $Id: where.test,v 1.32 2005/07/28 16:51:51 drh Exp $
|
||||
# $Id: where.test,v 1.33 2005/08/24 03:52:19 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -230,6 +230,7 @@ do_test where-1.41 {
|
||||
# Do the same kind of thing except use a join as the data source.
|
||||
#
|
||||
do_test where-2.1 {
|
||||
btree_breakpoint
|
||||
count {
|
||||
SELECT w, p FROM t2, t1
|
||||
WHERE x=q AND y=s AND r=8977
|
||||
@ -868,6 +869,41 @@ do_test where-10.4 {
|
||||
}
|
||||
} {50}
|
||||
|
||||
# Ticket #1376. The query below was causing a segfault.
|
||||
# The problem was the age-old error of calling realloc() on an
|
||||
# array while there are still pointers to individual elements of
|
||||
# that array.
|
||||
#
|
||||
do_test where-11.1 {
|
||||
btree_breakpoint
|
||||
execsql {
|
||||
CREATE TABLE t99(Dte INT, X INT);
|
||||
DELETE FROM t99 WHERE (Dte = 2451337) OR (Dte = 2451339) OR
|
||||
(Dte BETWEEN 2451345 AND 2451347) OR (Dte = 2451351) OR
|
||||
(Dte BETWEEN 2451355 AND 2451356) OR (Dte = 2451358) OR
|
||||
(Dte = 2451362) OR (Dte = 2451365) OR (Dte = 2451367) OR
|
||||
(Dte BETWEEN 2451372 AND 2451376) OR (Dte BETWEEN 2451382 AND 2451384) OR
|
||||
(Dte = 2451387) OR (Dte BETWEEN 2451389 AND 2451391) OR
|
||||
(Dte BETWEEN 2451393 AND 2451395) OR (Dte = 2451400) OR
|
||||
(Dte = 2451402) OR (Dte = 2451404) OR (Dte BETWEEN 2451416 AND 2451418) OR
|
||||
(Dte = 2451422) OR (Dte = 2451426) OR (Dte BETWEEN 2451445 AND 2451446) OR
|
||||
(Dte = 2451456) OR (Dte = 2451458) OR (Dte BETWEEN 2451465 AND 2451467) OR
|
||||
(Dte BETWEEN 2451469 AND 2451471) OR (Dte = 2451474) OR
|
||||
(Dte BETWEEN 2451477 AND 2451501) OR (Dte BETWEEN 2451503 AND 2451509) OR
|
||||
(Dte BETWEEN 2451511 AND 2451514) OR (Dte BETWEEN 2451518 AND 2451521) OR
|
||||
(Dte BETWEEN 2451523 AND 2451531) OR (Dte BETWEEN 2451533 AND 2451537) OR
|
||||
(Dte BETWEEN 2451539 AND 2451544) OR (Dte BETWEEN 2451546 AND 2451551) OR
|
||||
(Dte BETWEEN 2451553 AND 2451555) OR (Dte = 2451557) OR
|
||||
(Dte BETWEEN 2451559 AND 2451561) OR (Dte = 2451563) OR
|
||||
(Dte BETWEEN 2451565 AND 2451566) OR (Dte BETWEEN 2451569 AND 2451571) OR
|
||||
(Dte = 2451573) OR (Dte = 2451575) OR (Dte = 2451577) OR (Dte = 2451581) OR
|
||||
(Dte BETWEEN 2451583 AND 2451586) OR (Dte BETWEEN 2451588 AND 2451592) OR
|
||||
(Dte BETWEEN 2451596 AND 2451598) OR (Dte = 2451600) OR
|
||||
(Dte BETWEEN 2451602 AND 2451603) OR (Dte = 2451606) OR (Dte = 2451611);
|
||||
}
|
||||
} {}
|
||||
|
||||
|
||||
integrity_check {where-99.0}
|
||||
|
||||
finish_test
|
||||
|
Loading…
x
Reference in New Issue
Block a user