Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | More test cases and bug fixes with CSE. (CVS 4948) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7e8156129d6d240fe046bbc4ea269ebe |
User & Date: | drh 2008-04-01 03:27:39.000 |
Context
2008-04-01
| ||
05:07 | Fix the CSE mechanism so that it takes into account column affinity changes that might be imposed by comparison operators. (CVS 4949) (check-in: 91cc646e2b user: drh tags: trunk) | |
03:27 | More test cases and bug fixes with CSE. (CVS 4948) (check-in: 7e8156129d user: drh tags: trunk) | |
02:45 | Add a configure option for using gcov (makes things easier for versions of GCC that fail to build otherwise) (CVS 4947) (check-in: 7d1e797162 user: mlcreech tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.478 2008/04/01 03:27:39 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
201 202 203 204 205 206 207 208 209 210 211 212 213 214 | /* Get the VDBE program ready for execution */ if( v && pParse->nErr==0 && !db->mallocFailed ){ #ifdef SQLITE_DEBUG FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqlite3VdbeTrace(v, trace); #endif sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3, pParse->nTab+3, pParse->explain); pParse->rc = SQLITE_DONE; pParse->colNamesSet = 0; }else if( pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; } | > | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | /* Get the VDBE program ready for execution */ if( v && pParse->nErr==0 && !db->mallocFailed ){ #ifdef SQLITE_DEBUG FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqlite3VdbeTrace(v, trace); #endif assert( pParse->disableColCache==0 ); /* Disables and re-enables match */ sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3, pParse->nTab+3, pParse->explain); pParse->rc = SQLITE_DONE; pParse->colNamesSet = 0; }else if( pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; } |
︙ | ︙ |
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.361 2008/04/01 03:27:39 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
218 219 220 221 222 223 224 225 226 227 228 229 230 231 | CollSeq *p4; p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); sqlite3VdbeChangeP5(pParse->pVdbe, p5); return addr; } /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqlite3_malloc(). The calling function ** is responsible for making sure the node eventually gets freed. | > > > > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | CollSeq *p4; p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); sqlite3VdbeChangeP5(pParse->pVdbe, p5); if( p5 & SQLITE_AFF_MASK ){ sqlite3ExprExpireColumnCacheLines(pParse, in1, in1); sqlite3ExprExpireColumnCacheLines(pParse, in2, in2); } return addr; } /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqlite3_malloc(). The calling function ** is responsible for making sure the node eventually gets freed. |
︙ | ︙ | |||
1943 1944 1945 1946 1947 1948 1949 | } if( pParse->disableColCache==0 ){ i = pParse->iColCache; pParse->aColCache[i].iTable = iTable; pParse->aColCache[i].iColumn = iColumn; pParse->aColCache[i].iReg = iReg; i++; | | > | 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 | } if( pParse->disableColCache==0 ){ i = pParse->iColCache; pParse->aColCache[i].iTable = iTable; pParse->aColCache[i].iColumn = iColumn; pParse->aColCache[i].iReg = iReg; i++; if( i>=ArraySize(pParse->aColCache) ) i = 0; if( i>pParse->nColCache ) pParse->nColCache = i; pParse->iColCache = i; } return iReg; } /* ** Disable (+1) or enable (-1) the adding of new column cache entries. */ |
︙ | ︙ | |||
2042 2043 2044 2045 2046 2047 2048 | ** Return the register that the value ends up in. */ int sqlite3ExprWritableRegister(Parse *pParse, int iCurrent, int iTarget){ assert( pParse->pVdbe!=0 ); if( !usedAsColumnCache(pParse, iCurrent, iCurrent) ){ return iCurrent; } | > | > | 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 | ** Return the register that the value ends up in. */ int sqlite3ExprWritableRegister(Parse *pParse, int iCurrent, int iTarget){ assert( pParse->pVdbe!=0 ); if( !usedAsColumnCache(pParse, iCurrent, iCurrent) ){ return iCurrent; } if( iCurrent!=iTarget ){ sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, iCurrent, iTarget); } sqlite3ExprExpireColumnCacheLines(pParse, iTarget, iTarget); return iTarget; } /* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". |
︙ | ︙ |
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.685 2008/04/01 03:27:39 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if it was run ** (otherwise we get an empty default). |
︙ | ︙ | |||
1462 1463 1464 1465 1466 1467 1468 | int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int ckBase; /* Base register of data during check constraints */ int disableColCache; /* True to disable adding to column cache */ int nColCache; /* Number of entries in the column cache */ int iColCache; /* Next entry of the cache to replace */ | | > | 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 | int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int ckBase; /* Base register of data during check constraints */ int disableColCache; /* True to disable adding to column cache */ int nColCache; /* Number of entries in the column cache */ int iColCache; /* Next entry of the cache to replace */ struct yColCache { int iTable; /* Table cursor number */ int iColumn; /* Table column number */ char aff; /* Affinity. Or 0 if none specified */ int iReg; /* Register holding value of this column */ } aColCache[10]; /* One for each valid column cache entry */ u32 writeMask; /* Start a write transaction on these databases */ u32 cookieMask; /* Bitmask of schema verified databases */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ #ifndef SQLITE_OMIT_SHARED_CACHE |
︙ | ︙ |
Changes to test/cse.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # # Test cases designed to exercise and verify the logic for # factoring constant expressions out of loops and for # common subexpression eliminations. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # # Test cases designed to exercise and verify the logic for # factoring constant expressions out of loops and for # common subexpression eliminations. # # $Id: cse.test,v 1.2 2008/04/01 03:27:39 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl do_test cse-1.1 { execsql { |
︙ | ︙ | |||
61 62 63 64 65 66 67 | } {1 -1 -2 0 1 0 2 1 1 1 2 -2 -3 0 1 0 4 4 1 2} do_test cse-1.8 { execsql { SELECT a, a%a, a==a, a!=a, a<a, a<=a, a IS NULL, a NOT NULL, a FROM t1 } } {1 0 1 0 0 1 0 1 1 2 0 1 0 0 1 0 1 2} | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | } {1 -1 -2 0 1 0 2 1 1 1 2 -2 -3 0 1 0 4 4 1 2} do_test cse-1.8 { execsql { SELECT a, a%a, a==a, a!=a, a<a, a<=a, a IS NULL, a NOT NULL, a FROM t1 } } {1 0 1 0 0 1 0 1 1 2 0 1 0 0 1 0 1 2} # Overflow the column cache. Create queries involving more and more # columns until the cache overflows. Verify correct operation throughout. # do_test cse-2.1 { execsql { CREATE TABLE t2(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9, a10,a11,a12,a13,a14,a15,a16,a17,a18,a19, a20,a21,a22,a23,a24,a25,a26,a27,a28,a29, a30,a31,a32,a33,a34,a35,a36,a37,a38,a39, a40,a41,a42,a43,a44,a45,a46,a47,a48,a49); INSERT INTO t2 VALUES(0,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); SELECT * FROM t2; } } {0 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} for {set i 1} {$i<100} {incr i} { set n [expr {int(rand()*44)+5}] set colset {} set answer {} for {set j 0} {$j<$n} {incr j} { set r [expr {$j+int(rand()*5)}] if {$r>49} {set r [expr {99-$r}]} lappend colset a$j a$r lappend answer $j $r } set sql "SELECT [join $colset ,] FROM t2" do_test cse-2.2.$i { # explain $::sql execsql $::sql } $answer } finish_test |