Initial test cases and bug fixes in the CSE logic. (CVS 4946)
FossilOrigin-Name: e5aff09ac693946dc7ebb2f245b6434995b12155
This commit is contained in:
parent
e1349cb0f0
commit
652fbf55c5
15
manifest
15
manifest
@ -1,5 +1,5 @@
|
||||
C Break\sup\sthe\simplementation\sof\sOP_Move,\sOP_Copy,\sand\sOP_SCopy\sto\sreduce\nthe\snumber\sof\sbranch\sinstructions.\s(CVS\s4945)
|
||||
D 2008-04-01T00:36:10
|
||||
C Initial\stest\scases\sand\sbug\sfixes\sin\sthe\sCSE\slogic.\s(CVS\s4946)
|
||||
D 2008-04-01T01:42:41
|
||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||
F Makefile.in cf434ce8ca902e69126ae0f94fc9f7dc7428a5fa
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -95,7 +95,7 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||
F src/date.c e41ce4513fb0e359dc678d6bddb4ace135fe365d
|
||||
F src/delete.c 9573b07fbdaef0e68d63eb218e5874c7a162c727
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c 787f5fd4ee5ca58d4470603626f1b43ac2348faa
|
||||
F src/expr.c 35cccadd28e34079b00117494b0edf841c6b1b75
|
||||
F src/fault.c 83057e86815d473e526f7df0b0108dfdd022ff23
|
||||
F src/func.c c9e8c7ff4c45027edee89bde7adbf86a3a3b2afe
|
||||
F src/hash.c 53655c312280211444bfe23af6490a460aec2980
|
||||
@ -140,7 +140,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c 22297fffa6f00a6c6d44020fa13b1184a1bb372d
|
||||
F src/sqlite.h.in b1ac824d9fc163a5d2226ebf5990b09a02a11117
|
||||
F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
|
||||
F src/sqliteInt.h 79f4a09bc1e5b3ea50dae581294d8681b345a165
|
||||
F src/sqliteInt.h a04fe63ec5edda772a9313ac84d4b698ae73930b
|
||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||
F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a
|
||||
F src/tclsqlite.c 1367762764772a233643524c3585b4711a9adcda
|
||||
@ -248,6 +248,7 @@ F test/crash5.test c7ddcf7ca83abc19901b977732144234ac72a938
|
||||
F test/crash6.test 873d851c5ba2a46e0f9974c54e1d4a77d9a587d5
|
||||
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272
|
||||
F test/cse.test 963d0658bb6851e6e266b7dbeb66ef968f6926c6
|
||||
F test/date.test 8db95a0ba2c8f4c8762ce66859a036c51959a6be
|
||||
F test/default.test 252298e42a680146b1dd64f563b95bdf088d94fb
|
||||
F test/delete.test 57533e88e886608bf5ae0f394e14c2eb1b1f7754
|
||||
@ -620,7 +621,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P f61df8daa89f07dad2a0ded00c326ef35dead257
|
||||
R 70671ac2da4a3b5255caf0a8bf9dc874
|
||||
P 53e533d3a764d1973c24bffaacc505ea4b61a2b9
|
||||
R 00d768189a7178d88ec40a726cdc13f3
|
||||
U drh
|
||||
Z cb426daa3c0350483da8130288b38568
|
||||
Z 64e3c6f629ca2210e1712a4840620137
|
||||
|
@ -1 +1 @@
|
||||
53e533d3a764d1973c24bffaacc505ea4b61a2b9
|
||||
e5aff09ac693946dc7ebb2f245b6434995b12155
|
53
src/expr.c
53
src/expr.c
@ -12,7 +12,7 @@
|
||||
** This file contains routines used for analyzing expressions and
|
||||
** for generating VDBE code that evaluates expressions in SQLite.
|
||||
**
|
||||
** $Id: expr.c,v 1.359 2008/03/31 23:48:04 drh Exp $
|
||||
** $Id: expr.c,v 1.360 2008/04/01 01:42:41 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -2016,6 +2016,41 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if any register in the range iFrom..iTo (inclusive)
|
||||
** is used as part of the column cache.
|
||||
*/
|
||||
static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
|
||||
int i;
|
||||
for(i=0; i<pParse->nColCache; i++){
|
||||
int r = pParse->aColCache[i].iReg;
|
||||
if( r>=iFrom && r<=iTo ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Theres is a value in register iCurrent. We ultimately want
|
||||
** the value to be in register iTarget. It might be that
|
||||
** iCurrent and iTarget are the same register.
|
||||
**
|
||||
** We are going to modify the value, so we need to make sure it
|
||||
** is not a cached register. If iCurrent is a cached register,
|
||||
** then try to move the value over to iTarget. If iTarget is a
|
||||
** cached register, then clear the corresponding cache line.
|
||||
**
|
||||
** 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;
|
||||
}
|
||||
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".
|
||||
@ -2201,6 +2236,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
assert( TK_BITNOT==OP_BitNot );
|
||||
assert( TK_NOT==OP_Not );
|
||||
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
|
||||
inReg = sqlite3ExprWritableRegister(pParse, inReg, target);
|
||||
sqlite3VdbeAddOp1(v, op, inReg);
|
||||
break;
|
||||
}
|
||||
@ -2417,7 +2453,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
aListelem = pEList->a;
|
||||
nExpr = pEList->nExpr;
|
||||
endLabel = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3ExprColumnCacheDisable(pParse, 1);
|
||||
if( (pX = pExpr->pLeft)!=0 ){
|
||||
cacheX = *pX;
|
||||
cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, ®Free1);
|
||||
@ -2427,6 +2462,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
opCompare.pLeft = &cacheX;
|
||||
pTest = &opCompare;
|
||||
}
|
||||
sqlite3ExprColumnCacheDisable(pParse, 1);
|
||||
for(i=0; i<nExpr; i=i+2){
|
||||
if( pX ){
|
||||
opCompare.pRight = aListelem[i].pExpr;
|
||||
@ -3086,19 +3122,6 @@ void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if any register in the range iFrom..iTo (inclusive)
|
||||
** is used as part of the column cache.
|
||||
*/
|
||||
static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
|
||||
int i;
|
||||
for(i=0; i<pParse->nColCache; i++){
|
||||
int r = pParse->aColCache[i].iReg;
|
||||
if( r>=iFrom && r<=iTo ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate or deallocate temporary use registers during code generation.
|
||||
*/
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.683 2008/03/31 23:48:05 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.684 2008/04/01 01:42:41 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@ -1842,6 +1842,7 @@ void sqlite3ExprCodeMove(Parse*, int, int);
|
||||
void sqlite3ExprClearColumnCache(Parse*, int);
|
||||
void sqlite3ExprColumnCacheDisable(Parse*, int);
|
||||
void sqlite3ExprExpireColumnCacheLines(Parse*, int, int);
|
||||
int sqlite3ExprWritableRegister(Parse*,int,int);
|
||||
int sqlite3ExprCode(Parse*, Expr*, int);
|
||||
int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
|
||||
int sqlite3ExprCodeTarget(Parse*, Expr*, int);
|
||||
|
69
test/cse.test
Normal file
69
test/cse.test
Normal file
@ -0,0 +1,69 @@
|
||||
# 2008 April 1
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# 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.1 2008/04/01 01:42:41 drh Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_test cse-1.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e, f);
|
||||
INSERT INTO t1 VALUES(1,11,12,13,14,15);
|
||||
INSERT INTO t1 VALUES(2,21,22,23,24,25);
|
||||
}
|
||||
execsql {
|
||||
SELECT b, -b, ~b, NOT b, NOT NOT b, b-b, b+b, b*b, b/b, b FROM t1
|
||||
}
|
||||
} {11 -11 -12 0 1 0 22 121 1 11 21 -21 -22 0 1 0 42 441 1 21}
|
||||
do_test cse-1.2 {
|
||||
execsql {
|
||||
SELECT b, b%b, b==b, b!=b, b<b, b<=b, b IS NULL, b NOT NULL, b FROM t1
|
||||
}
|
||||
} {11 0 1 0 0 1 0 1 11 21 0 1 0 0 1 0 1 21}
|
||||
do_test cse-1.3 {
|
||||
execsql {
|
||||
SELECT b, abs(b), coalesce(b,-b,NOT b,c,NOT c), c, -c FROM t1;
|
||||
}
|
||||
} {11 11 11 12 -12 21 21 21 22 -22}
|
||||
do_test cse-1.4 {
|
||||
execsql {
|
||||
SELECT CASE WHEN a==1 THEN b ELSE c END, b, c FROM t1
|
||||
}
|
||||
} {11 11 12 22 21 22}
|
||||
do_test cse-1.5 {
|
||||
execsql {
|
||||
SELECT CASE a WHEN 1 THEN b WHEN 2 THEN c ELSE d END, b, c, d FROM t1
|
||||
}
|
||||
} {11 11 12 13 22 21 22 23}
|
||||
do_test cse-1.6 {
|
||||
execsql {
|
||||
SELECT CASE b WHEN 11 THEN -b WHEN 21 THEN -c ELSE -d END, b, c, d FROM t1
|
||||
}
|
||||
} {-11 11 12 13 -22 21 22 23}
|
||||
do_test cse-1.7 {
|
||||
execsql {
|
||||
SELECT a, -a, ~a, NOT a, NOT NOT a, a-a, a+a, a*a, a/a, a FROM t1
|
||||
}
|
||||
} {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}
|
||||
|
||||
|
||||
finish_test
|
Loading…
Reference in New Issue
Block a user