mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-06 15:49:35 +03:00
Fix a code generator bug caused by the new CSE optimization. Add test cases
to prevent a recurrence. (CVS 5011) FossilOrigin-Name: d04246a46399e839e70b1bd57e209f80143f0d5b
This commit is contained in:
24
manifest
24
manifest
@@ -1,5 +1,5 @@
|
||||
C Fix\sa\sbug\sin\sthe\sRTRIM\scollating\ssequence\sdiscovered\swhile\sworking\non\scondition/decision\sbranch\scoverage.\s\sIncrease\stest\scoverage\sof\nthe\sdate/time\sfunctions.\s(CVS\s5010)
|
||||
D 2008-04-15T04:02:41
|
||||
C Fix\sa\scode\sgenerator\sbug\scaused\sby\sthe\snew\sCSE\soptimization.\s\sAdd\stest\scases\nto\sprevent\sa\srecurrence.\s(CVS\s5011)
|
||||
D 2008-04-15T12:14:22
|
||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||
F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@@ -95,7 +95,7 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||
F src/date.c e41ce4513fb0e359dc678d6bddb4ace135fe365d
|
||||
F src/delete.c 555cedf9e59db9ead1c2f8db0c4344201ea7caaa
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c 4b6cc2496999bda069a9e00db9c2d7ccdf01a129
|
||||
F src/expr.c 7aecda0fb4f078718281a9b56993677c1f45a399
|
||||
F src/fault.c 83057e86815d473e526f7df0b0108dfdd022ff23
|
||||
F src/func.c c9e8c7ff4c45027edee89bde7adbf86a3a3b2afe
|
||||
F src/hash.c 522a8f5a23cf18fe5845afee7263c5be76c25ca2
|
||||
@@ -135,12 +135,12 @@ F src/pragma.c e659c9e443d11854cff2fd250012365ae0ca81ba
|
||||
F src/prepare.c adc7e1fc08dfbab63cd213d4c0aff8f3fa70d477
|
||||
F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d
|
||||
F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
|
||||
F src/select.c 1abe53c844f536a79cc11b19127c8e6d47a87b20
|
||||
F src/select.c 5b8824a326a923876827fa8771c5e4e9e3a7faa1
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c 22297fffa6f00a6c6d44020fa13b1184a1bb372d
|
||||
F src/sqlite.h.in 824f823b341e9c979f82edebf710c87b74d1b7f5
|
||||
F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
|
||||
F src/sqliteInt.h 6e6e847b7315e9609ab79dba6d68748b7ad3e214
|
||||
F src/sqliteInt.h ef381f6a169d824e8ba54a389187836c4cd48420
|
||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||
F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a
|
||||
F src/tclsqlite.c c4892f48927cb3db19faeb448ea8abddfd4846a8
|
||||
@@ -158,7 +158,7 @@ F src/test_autoext.c 5e892ab84aece3f0428920bf46923f16ac83962a
|
||||
F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c
|
||||
F src/test_config.c b910754c5ba311abf149457cdbfd66144e715b35
|
||||
F src/test_devsym.c cee1aecaa90c895030399ca4ae38f84a08038f8a
|
||||
F src/test_func.c ef4ef3230b6346031bca2762bbc8b95ec7e0451a
|
||||
F src/test_func.c f4aafa10f17d52c43a64b47717265802e6e552b3
|
||||
F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d
|
||||
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
||||
F src/test_malloc.c c92a65e8f9b31bb2b332448d92d2016c000a963d
|
||||
@@ -175,7 +175,7 @@ F src/update.c d6f214aad7eab5aaec5f966058b0828b3f7d6706
|
||||
F src/utf.c 8c94fa10efc78c2568d08d436acc59df4df7191b
|
||||
F src/util.c 8b17ea7ad27914c6e2c4a377ca7db743fb7e29a8
|
||||
F src/vacuum.c 3524411bfb58aac0d87eadd3e5b7cd532772af30
|
||||
F src/vdbe.c 444ab9ecc91f3c04b2b29ae604458426aa674fa6
|
||||
F src/vdbe.c e4a3df1221a8ee8025c7132cf8ab6bc88eae4e02
|
||||
F src/vdbe.h bfd84bda447f39cb599302c7ec85067dae20453c
|
||||
F src/vdbeInt.h 0b96efdeecb0803e504bf1c16b198f87c91d6019
|
||||
F src/vdbeapi.c 0e1b5a808bb0e556f2a975eb7d11fd3153e922bf
|
||||
@@ -221,7 +221,7 @@ F test/cache.test 3ff445c445742a7b6b9ba6e1d62a25263f9424b9
|
||||
F test/capi2.test cc64df7560a96f848f919ea2926c60acf639684b
|
||||
F test/capi3.test 8113010cd06a94b7ac72524858968069b7cac8e3
|
||||
F test/capi3b.test 664eb55318132f292f2c436f90906f578cad6b97
|
||||
F test/capi3c.test d704c1b9dff6a2749c758845d1a0358155642484
|
||||
F test/capi3c.test c024e42d2341026ddffd79a7dd864c3555d06ccd
|
||||
F test/cast.test ce8f14fc80f70b30ed984480cc0d8914a459e8f9
|
||||
F test/check.test 024ed399600b799160378cf9d9f436bdf5dfd184
|
||||
F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04
|
||||
@@ -322,7 +322,7 @@ F test/fts3ao.test 0aa29dd4fc1c8d46b1f7cfe5926f7ac97551bea9
|
||||
F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa
|
||||
F test/fts3b.test b3a25180a633873d37d86e1ccd00ed690d37237a
|
||||
F test/fts3near.test 2d4dadcaac5025ab65bb87e66c45f39e92966194
|
||||
F test/func.test 4ae1fb477bb6dbeba9ae8d09f258663c29d2f4aa
|
||||
F test/func.test 5227e6e6e9df33f5e771ef164f634b7d4f6d6a55
|
||||
F test/fuzz.test 62fc19dd36a427777fd671b569df07166548628a
|
||||
F test/fuzz2.test ea38692ce2da99ad79fe0be5eb1a452c1c4d37bb
|
||||
F test/fuzz_common.tcl ff4bc2dfc465f6878f8e2d819620914365382731
|
||||
@@ -629,7 +629,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P b7ffc6f0f33b14430ab84a6c60110bc07514f056
|
||||
R 39eb77e983bc30708ab7dd070f56763f
|
||||
P c5435f71efa0b34c759bac4a15fdf43abf39ddfc
|
||||
R 6394eb4f4998e17e7d31653fe6234a16
|
||||
U drh
|
||||
Z c185fe19fbf753e76e5d68ad2182c5d1
|
||||
Z de8ad5aae1cda6ab722570506572bc31
|
||||
|
||||
@@ -1 +1 @@
|
||||
c5435f71efa0b34c759bac4a15fdf43abf39ddfc
|
||||
d04246a46399e839e70b1bd57e209f80143f0d5b
|
||||
31
src/expr.c
31
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.366 2008/04/11 15:36:03 drh Exp $
|
||||
** $Id: expr.c,v 1.367 2008/04/15 12:14:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -2103,6 +2103,24 @@ int sqlite3ExprWritableRegister(Parse *pParse, int iCurrent, int iTarget){
|
||||
return iTarget;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the last instruction coded is an ephemeral copy of any of
|
||||
** the registers in the nReg registers beginning with iReg, then
|
||||
** convert the last instruction from OP_SCopy to OP_Copy.
|
||||
*/
|
||||
void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){
|
||||
int addr;
|
||||
VdbeOp *pOp;
|
||||
Vdbe *v;
|
||||
|
||||
v = pParse->pVdbe;
|
||||
addr = sqlite3VdbeCurrentAddr(v);
|
||||
pOp = sqlite3VdbeGetOp(v, addr-1);
|
||||
if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){
|
||||
pOp->opcode = OP_Copy;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code into the current Vdbe to evaluate the given
|
||||
** expression. Attempt to store the results in register "target".
|
||||
@@ -2374,7 +2392,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
if( pList ){
|
||||
nExpr = pList->nExpr;
|
||||
r1 = sqlite3GetTempRange(pParse, nExpr);
|
||||
sqlite3ExprCodeExprList(pParse, pList, r1);
|
||||
sqlite3ExprCodeExprList(pParse, pList, r1, 1);
|
||||
}else{
|
||||
nExpr = r1 = 0;
|
||||
}
|
||||
@@ -2804,7 +2822,8 @@ void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
|
||||
int sqlite3ExprCodeExprList(
|
||||
Parse *pParse, /* Parsing context */
|
||||
ExprList *pList, /* The expression list to be coded */
|
||||
int target /* Where to write results */
|
||||
int target, /* Where to write results */
|
||||
int doHardCopy /* Call sqlite3ExprHardCopy on each element if true */
|
||||
){
|
||||
struct ExprList_item *pItem;
|
||||
int i, n;
|
||||
@@ -2814,9 +2833,9 @@ int sqlite3ExprCodeExprList(
|
||||
}
|
||||
assert( target>0 );
|
||||
n = pList->nExpr;
|
||||
for(pItem=pList->a, i=n; i>0; i--, pItem++){
|
||||
sqlite3ExprCode(pParse, pItem->pExpr, target);
|
||||
target++;
|
||||
for(pItem=pList->a, i=0; i<n; i++, pItem++){
|
||||
sqlite3ExprCode(pParse, pItem->pExpr, target+i);
|
||||
if( doHardCopy ) sqlite3ExprHardCopy(pParse, target, n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
12
src/select.c
12
src/select.c
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle SELECT statements in SQLite.
|
||||
**
|
||||
** $Id: select.c,v 1.426 2008/04/10 13:33:18 drh Exp $
|
||||
** $Id: select.c,v 1.427 2008/04/15 12:14:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -422,7 +422,7 @@ static void pushOntoSorter(
|
||||
int nExpr = pOrderBy->nExpr;
|
||||
int regBase = sqlite3GetTempRange(pParse, nExpr+2);
|
||||
int regRecord = sqlite3GetTempReg(pParse);
|
||||
sqlite3ExprCodeExprList(pParse, pOrderBy, regBase);
|
||||
sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
|
||||
sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1);
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
|
||||
@@ -580,9 +580,7 @@ static void selectInnerLoop(
|
||||
/* If the destination is an EXISTS(...) expression, the actual
|
||||
** values returned by the SELECT are not required.
|
||||
*/
|
||||
for(i=0; i<nResultCol; i++){
|
||||
sqlite3ExprCode(pParse, pEList->a[i].pExpr, regResult+i);
|
||||
}
|
||||
sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Callback);
|
||||
}
|
||||
nColumn = nResultCol;
|
||||
|
||||
@@ -2902,7 +2900,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
if( pList ){
|
||||
nArg = pList->nExpr;
|
||||
regAgg = sqlite3GetTempRange(pParse, nArg);
|
||||
sqlite3ExprCodeExprList(pParse, pList, regAgg);
|
||||
sqlite3ExprCodeExprList(pParse, pList, regAgg, 0);
|
||||
}else{
|
||||
nArg = 0;
|
||||
regAgg = 0;
|
||||
@@ -3432,7 +3430,7 @@ int sqlite3Select(
|
||||
}
|
||||
}
|
||||
regBase = sqlite3GetTempRange(pParse, nCol);
|
||||
sqlite3ExprCodeExprList(pParse, pGroupBy, regBase);
|
||||
sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
|
||||
j = nGroupBy+1;
|
||||
for(i=0; i<sAggInfo.nColumn; i++){
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.691 2008/04/10 16:47:42 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.692 2008/04/15 12:14:22 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@@ -1872,12 +1872,13 @@ void sqlite3ExprCodeMove(Parse*, int, int);
|
||||
void sqlite3ExprClearColumnCache(Parse*, int);
|
||||
void sqlite3ExprCacheAffinityChange(Parse*, int, int);
|
||||
int sqlite3ExprWritableRegister(Parse*,int,int);
|
||||
void sqlite3ExprHardCopy(Parse*,int,int);
|
||||
int sqlite3ExprCode(Parse*, Expr*, int);
|
||||
int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
|
||||
int sqlite3ExprCodeTarget(Parse*, Expr*, int);
|
||||
int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
|
||||
void sqlite3ExprCodeConstants(Parse*, Expr*);
|
||||
int sqlite3ExprCodeExprList(Parse*, ExprList*, int);
|
||||
int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int);
|
||||
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
|
||||
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
|
||||
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
** Code for testing all sorts of SQLite interfaces. This code
|
||||
** implements new SQL functions used by the test scripts.
|
||||
**
|
||||
** $Id: test_func.c,v 1.4 2008/04/10 17:14:07 drh Exp $
|
||||
** $Id: test_func.c,v 1.5 2008/04/15 12:14:22 drh Exp $
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
#include "tcl.h"
|
||||
@@ -204,6 +204,33 @@ static void test_error(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This function takes two arguments. It performance UTF-8/16 type
|
||||
** conversions on the first argument then returns a copy of the second
|
||||
** argument.
|
||||
**
|
||||
** This function is used in cases such as the following:
|
||||
**
|
||||
** SELECT test_isolation(x,x) FROM t1;
|
||||
**
|
||||
** We want to verify that the type conversions that occur on the
|
||||
** first argument do not invalidate the second argument.
|
||||
*/
|
||||
static void test_isolation(
|
||||
sqlite3_context *pCtx,
|
||||
int nArg,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
sqlite3_value_text16(argv[0]);
|
||||
sqlite3_value_text(argv[0]);
|
||||
sqlite3_value_text16(argv[0]);
|
||||
sqlite3_value_text(argv[0]);
|
||||
#endif
|
||||
sqlite3_result_value(pCtx, argv[1]);
|
||||
}
|
||||
|
||||
|
||||
static int registerTestFunctions(sqlite3 *db){
|
||||
static const struct {
|
||||
char *zName;
|
||||
@@ -218,6 +245,7 @@ static int registerTestFunctions(sqlite3 *db){
|
||||
{ "test_auxdata", -1, SQLITE_UTF8, test_auxdata},
|
||||
{ "test_error", 1, SQLITE_UTF8, test_error},
|
||||
{ "test_error", 2, SQLITE_UTF8, test_error},
|
||||
{ "test_isolation", 2, SQLITE_UTF8, test_isolation},
|
||||
};
|
||||
int i;
|
||||
extern int Md5_Register(sqlite3*);
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
** in this file for details. If in doubt, do not deviate from existing
|
||||
** commenting and indentation practices when changing or adding code.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.729 2008/04/10 14:00:10 drh Exp $
|
||||
** $Id: vdbe.c,v 1.730 2008/04/15 12:14:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -880,6 +880,7 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
|
||||
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem;
|
||||
pOut->zMalloc = 0;
|
||||
pOut->flags |= MEM_Static;
|
||||
pOut->flags &= ~MEM_Dyn;
|
||||
if( pOp->p4type==P4_DYNAMIC ){
|
||||
sqlite3_free(pOp->p4.z);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# This is a copy of the capi3.test file that has been adapted to
|
||||
# test the new sqlite3_prepare_v2 interface.
|
||||
#
|
||||
# $Id: capi3c.test,v 1.17 2008/04/10 17:14:07 drh Exp $
|
||||
# $Id: capi3c.test,v 1.18 2008/04/15 12:14:22 drh Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@@ -1266,5 +1266,36 @@ do_test capi3c-22.3 {
|
||||
} {SQLITE_EMPTY}
|
||||
sqlite3_finalize $STMT
|
||||
|
||||
# For a multi-column result set where the same table column is repeated
|
||||
# in multiple columns of the output, verify that doing a UTF-8 to UTF-16
|
||||
# conversion (or vice versa) on one column does not change the value of
|
||||
# the second.
|
||||
#
|
||||
do_test capi3c-23.1 {
|
||||
set STMT [sqlite3_prepare_v2 db {SELECT b,b,b,b FROM t1} -1 TAIL]
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_ROW}
|
||||
do_test capi3c-23.2 {
|
||||
sqlite3_column_text16 $STMT 0
|
||||
sqlite3_column_text $STMT 1
|
||||
} {one}
|
||||
do_test capi3c-23.3 {
|
||||
sqlite3_column_text16 $STMT 2
|
||||
sqlite3_column_text $STMT 3
|
||||
} {one}
|
||||
sqlite3_finalize $STMT
|
||||
do_test capi3c-23.4 {
|
||||
set STMT [sqlite3_prepare_v2 db {SELECT b||'x',b,b,b FROM t1} -1 TAIL]
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_ROW}
|
||||
do_test capi3c-23.5 {
|
||||
sqlite3_column_text16 $STMT 0
|
||||
sqlite3_column_text $STMT 1
|
||||
} {one}
|
||||
do_test capi3c-23.6 {
|
||||
sqlite3_column_text16 $STMT 2
|
||||
sqlite3_column_text $STMT 3
|
||||
} {one}
|
||||
sqlite3_finalize $STMT
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing built-in functions.
|
||||
#
|
||||
# $Id: func.test,v 1.76 2008/04/10 17:14:07 drh Exp $
|
||||
# $Id: func.test,v 1.77 2008/04/15 12:14:22 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -930,4 +930,11 @@ do_test func-24.6 {
|
||||
}
|
||||
} {BEGIN-this,program,is,free,software}
|
||||
|
||||
# Use the test_isolation function to make sure that type conversions
|
||||
# on function arguments do not effect subsequent arguments.
|
||||
#
|
||||
do_test func-25.1 {
|
||||
execsql {SELECT test_isolation(t1,t1) FROM tbl1}
|
||||
} {this program is free software}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user