Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a bug in where.c where a non-temp register was being incorrectly deallocated. Ticket #3408. (CVS 5758) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
59d2e89e2181c26b18eac68ccc80ea30 |
User & Date: | danielk1977 2008-10-01 08:43:03.000 |
Context
2008-10-01
| ||
13:55 | Adjust the memory usage bounds on the memsubsys1.test script so that it works on amd64. (CVS 5759) (check-in: aabde23fe1 user: drh tags: trunk) | |
08:43 | Fix a bug in where.c where a non-temp register was being incorrectly deallocated. Ticket #3408. (CVS 5758) (check-in: 59d2e89e21 user: danielk1977 tags: trunk) | |
2008-09-30
| ||
17:18 | Add some testcase() and assert() macros to btree.c to aid with testing recent changes. (CVS 5757) (check-in: fb461b78df user: drh tags: trunk) | |
Changes
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is responsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is responsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** 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.323 2008/10/01 08:43:03 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
1780 1781 1782 1783 1784 1785 1786 | WhereLevel *pLevel, /* When level of the FROM clause we are working on */ int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ | | < < | 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 | WhereLevel *pLevel, /* When level of the FROM clause we are working on */ int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ assert( iTarget>0 ); if( pX->op==TK_EQ ){ iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ |
︙ | ︙ | |||
2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 | if( pLevel->flags & WHERE_ROWID_EQ ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" ** construct. */ int r1; pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0); assert( pTerm!=0 ); assert( pTerm->pExpr!=0 ); assert( pTerm->leftCursor==iCur ); assert( omitTable==0 ); | > | | | 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 | if( pLevel->flags & WHERE_ROWID_EQ ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" ** construct. */ int r1; int rtmp = sqlite3GetTempReg(pParse); pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0); assert( pTerm!=0 ); assert( pTerm->pExpr!=0 ); assert( pTerm->leftCursor==iCur ); assert( omitTable==0 ); r1 = codeEqualityTerm(pParse, pTerm, pLevel, rtmp); nxt = pLevel->nxt; sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, nxt); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, nxt, r1); sqlite3ReleaseTempReg(pParse, rtmp); VdbeComment((v, "pk")); pLevel->op = OP_Noop; }else if( pLevel->flags & WHERE_ROWID_RANGE ){ /* Case 2: We have an inequality comparison against the ROWID field. */ int testOp = OP_Noop; int start; |
︙ | ︙ |
Changes to test/where.test.
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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the use of indices in WHERE clases. # | | | 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. # #*********************************************************************** # 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.48 2008/10/01 08:43:03 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Build some test data # do_test where-1.0 { |
︙ | ︙ | |||
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 | do_test where-15.1 { execsql { CREATE TEMP TABLE t1 (a, b, c, d, e); CREATE TEMP TABLE t2 (f); SELECT t1.e AS alias FROM t2, t1 WHERE alias = 1 ; } } {} integrity_check {where-99.0} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 | do_test where-15.1 { execsql { CREATE TEMP TABLE t1 (a, b, c, d, e); CREATE TEMP TABLE t2 (f); SELECT t1.e AS alias FROM t2, t1 WHERE alias = 1 ; } } {} # Ticket #3408. # # The branch of code in where.c that generated rowid lookups was # incorrectly deallocating a constant register, meaning that if the # vdbe code ran more than once, the second time around the constant # value may have been clobbered by some other value. # do_test where-16.1 { execsql { CREATE TABLE a1(id INTEGER PRIMARY KEY, v); CREATE TABLE a2(id INTEGER PRIMARY KEY, v); INSERT INTO a1 VALUES(1, 'one'); INSERT INTO a1 VALUES(2, 'two'); INSERT INTO a2 VALUES(1, 'one'); INSERT INTO a2 VALUES(2, 'two'); } } {} do_test where-16.2 { execsql { SELECT * FROM a2 CROSS JOIN a1 WHERE a1.id=1 AND a1.v='one'; } } {1 one 1 one 2 two 1 one} # The actual problem reported in #3408. do_test where-16.3 { execsql { CREATE TEMP TABLE foo(idx INTEGER); INSERT INTO foo VALUES(1); INSERT INTO foo VALUES(1); INSERT INTO foo VALUES(1); INSERT INTO foo VALUES(2); INSERT INTO foo VALUES(2); CREATE TEMP TABLE bar(stuff INTEGER); INSERT INTO bar VALUES(100); INSERT INTO bar VALUES(200); INSERT INTO bar VALUES(300); } } {} do_test where-16.4 { execsql { SELECT bar.RowID id FROM foo, bar WHERE foo.idx = bar.RowID AND id = 2; } } {2 2} integrity_check {where-99.0} finish_test |