diff --git a/manifest b/manifest index 80de9a65a3..e62646f183 100644 --- a/manifest +++ b/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 diff --git a/manifest.uuid b/manifest.uuid index 8e9af34c95..aa53a41cdd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a715e7001247e84e0982335570593f0802774635 \ No newline at end of file +9f9a257123274779150cbc290b9f86a09b3b2c03 \ No newline at end of file diff --git a/src/where.c b/src/where.c index ab97b3be19..4e355e8022 100644 --- a/src/where.c +++ b/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 " */ i16 leftColumn; /* Column number of X in "X " */ @@ -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; } } diff --git a/test/where.test b/test/where.test index f5fb8126e1..6e2995353b 100644 --- a/test/where.test +++ b/test/where.test @@ -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