1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Updated testing of cursor-hints. Remove the test_cursorhint.c file and

associated logic in the core and do tests based purely on the newly enhanced
EXPLAIN output.

FossilOrigin-Name: bf383e665a191a4f33a540d1240960a922e22813
This commit is contained in:
drh
2015-08-14 20:08:13 +00:00
parent 2f2b02785a
commit 1eb6eeb829
7 changed files with 102 additions and 222 deletions

View File

@ -262,7 +262,6 @@ TESTSRC = \
$(TOP)/src/test_blob.c \
$(TOP)/src/test_btree.c \
$(TOP)/src/test_config.c \
$(TOP)/src/test_cursorhint.c \
$(TOP)/src/test_demovfs.c \
$(TOP)/src/test_devsym.c \
$(TOP)/src/test_fs.c \

View File

@ -1,5 +1,5 @@
C Fix\sthe\scursor\shint\smechanism\sso\sthat\sit\sdoes\sthe\sright\sthing\sfor\sindexed\nlookups.
D 2015-08-14T18:50:04.420
C Updated\stesting\sof\scursor-hints.\s\sRemove\sthe\stest_cursorhint.c\sfile\sand\nassociated\slogic\sin\sthe\score\sand\sdo\stests\sbased\spurely\son\sthe\snewly\senhanced\nEXPLAIN\soutput.
D 2015-08-14T20:08:13.528
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -256,7 +256,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 389329247c56b23329a9285155106cd6b6ebad42
F main.mk 73167b34b0e67c0be32c1da2d988a376851c9ab1
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk 0e7f04a8eb90f92259e47d80110e4e98d7ce337a
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@ -344,7 +344,7 @@ F src/sqliteInt.h cbd6d166c5f8aa17e4be463ccefef41cd1d40286
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
F src/tclsqlite.c 72f4dd747d5604a508bbb6935817d3afe5ffd6e2
F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649
F src/test1.c d339ae9b9baf9221c657c9628c9061d88bd831f6
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
@ -360,7 +360,6 @@ F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
F src/test_config.c fb2e5d354d9a077f5fbb261652eff4787deb104f
F src/test_cursorhint.c bba837177d1693037f5c83dcb443cf453ee656ed
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
@ -399,7 +398,7 @@ F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c bc9dd64b5db544218b871b66243871c202b2781f
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c 74561c2d15895f930f08e4216d454efaaaf530c4
F src/vdbe.c 882cac44eb4f53d18e31c79fc1741d400016f867
F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832
F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2
F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4
@ -561,7 +560,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/cursorhint.test e55ad8c466327ffb3511b60007102bca22314d0a
F test/cursorhint.test c3844bed3eec3506b38b98ab5f0ca22a4ab9ecb4
F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
@ -1375,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a
R 020be40332ddb39fbaad6fc302316e47
P 581e3d4988e98975fea5daaeb9f854c54a4976b7
R 32fb6312a84d28df618932a2d55ba493
U drh
Z 56068f8a083e66d3150e6ce38cb011fe
Z 247ce995f99250cbca60587acaa0c7c9

View File

@ -1 +1 @@
581e3d4988e98975fea5daaeb9f854c54a4976b7
bf383e665a191a4f33a540d1240960a922e22813

View File

@ -3739,7 +3739,6 @@ static void init_all(Tcl_Interp *interp){
extern int Sqlitetestasync_Init(Tcl_Interp*);
extern int Sqlitetest_autoext_Init(Tcl_Interp*);
extern int Sqlitetest_blob_Init(Tcl_Interp*);
extern int Sqlitetest_cursorhint_Init(Tcl_Interp*);
extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
extern int Sqlitetest_func_Init(Tcl_Interp*);
extern int Sqlitetest_hexio_Init(Tcl_Interp*);
@ -3785,8 +3784,6 @@ static void init_all(Tcl_Interp *interp){
Sqlitetestasync_Init(interp);
Sqlitetest_autoext_Init(interp);
Sqlitetest_blob_Init(interp);
Sqlitetest_cursorhint_Init(interp);
Sqlitetest_demovfs_Init(interp);
Sqlitetest_demovfs_Init(interp);
Sqlitetest_func_Init(interp);
Sqlitetest_hexio_Init(interp);

View File

@ -1,162 +0,0 @@
/*
** 2008 March 19
**
** 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.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces. This code
** implements new SQL functions used by the test scripts.
*/
#include "sqlite3.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sqliteInt.h"
#include "vdbeInt.h"
struct CursorHintGlobal {
Tcl_Interp *interp;
Tcl_Obj *pScript;
} cursorhintglobal;
static char *exprToString(Mem *aMem, Expr *pExpr){
char *zRet = 0;
char *zBinOp = 0;
switch( pExpr->op ){
case TK_STRING:
zRet = sqlite3_mprintf("%Q", pExpr->u.zToken);
break;
case TK_INTEGER:
zRet = sqlite3_mprintf("%d", pExpr->u.iValue);
break;
case TK_NULL:
zRet = sqlite3_mprintf("%s", "NULL");
break;
case TK_REGISTER: {
Mem *pMem = &aMem[pExpr->iTable];
if( pMem->flags & MEM_Int ){
zRet = sqlite3_mprintf("%lld", pMem->u.i);
}
else if( pMem->flags & MEM_Real ){
zRet = sqlite3_mprintf("%f", pMem->u.r);
}
else if( pMem->flags & MEM_Str ){
zRet = sqlite3_mprintf("%.*Q", pMem->n, pMem->z);
}
else if( pMem->flags & MEM_Blob ){
}
else{
zRet = sqlite3_mprintf("%s", "NULL");
}
break;
}
case TK_COLUMN: {
zRet = sqlite3_mprintf("col(%d)", (int)pExpr->iColumn);
break;
}
case TK_LT: zBinOp = "<"; break;
case TK_LE: zBinOp = "<="; break;
case TK_GT: zBinOp = ">"; break;
case TK_GE: zBinOp = ">="; break;
case TK_NE: zBinOp = "!="; break;
case TK_EQ: zBinOp = "=="; break;
case TK_IS: zBinOp = "IS"; break;
case TK_ISNOT: zBinOp = "IS NOT"; break;
case TK_AND: zBinOp = "AND"; break;
case TK_OR: zBinOp = "OR"; break;
case TK_PLUS: zBinOp = "+"; break;
case TK_STAR: zBinOp = "*"; break;
case TK_MINUS: zBinOp = "-"; break;
case TK_REM: zBinOp = "%"; break;
case TK_BITAND: zBinOp = "&"; break;
case TK_BITOR: zBinOp = "|"; break;
case TK_SLASH: zBinOp = "/"; break;
case TK_LSHIFT: zBinOp = "<<"; break;
case TK_RSHIFT: zBinOp = ">>"; break;
case TK_CONCAT: zBinOp = "||"; break;
default:
zRet = sqlite3_mprintf("%s", "expr");
break;
}
if( zBinOp ){
zRet = sqlite3_mprintf("(%z %s %z)",
exprToString(aMem, pExpr->pLeft),
zBinOp,
exprToString(aMem, pExpr->pRight)
);
}
return zRet;
}
void sqlite3BtreeCursorHintTest(Mem *aMem, Expr *pExpr){
if( cursorhintglobal.pScript ){
Tcl_Obj *pEval = Tcl_DuplicateObj(cursorhintglobal.pScript);
char *zExpr;
Tcl_Obj *pObj;
Tcl_IncrRefCount(pEval);
zExpr = exprToString(aMem, pExpr);
pObj = Tcl_NewStringObj(zExpr, -1);
sqlite3_free(zExpr);
Tcl_ListObjAppendElement(cursorhintglobal.interp, pEval, pObj);
Tcl_EvalObjEx(cursorhintglobal.interp, pEval, TCL_GLOBAL_ONLY);
Tcl_DecrRefCount(pEval);
}
}
/*
** Usage: cursorhint_hook SCRIPT
*/
static int install_cursorhint_hook(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
if( objc!=1 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "?SCRIPT?");
return TCL_ERROR;
}
if( cursorhintglobal.pScript ){
Tcl_DecrRefCount(cursorhintglobal.pScript);
memset(&cursorhintglobal, 0, sizeof(cursorhintglobal));
}
if( objc==2 ){
cursorhintglobal.interp = interp;
cursorhintglobal.pScript = Tcl_DuplicateObj(objv[1]);
}
return TCL_OK;
}
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest_cursorhint_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
} aObjCmd[] = {
{ "cursorhint_hook", install_cursorhint_hook },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
}
sqlite3_initialize();
return TCL_OK;
}

View File

@ -6570,10 +6570,6 @@ case OP_CursorHint: {
pC = p->apCsr[pOp->p1];
if( pC ){
sqlite3BtreeCursorHint(pC->pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem);
#ifdef SQLITE_TEST
void sqlite3BtreeCursorHintTest(Mem*, Expr*);
sqlite3BtreeCursorHintTest(p->aMem, pOp->p4.pExpr);
#endif
}
break;
}

View File

@ -16,57 +16,108 @@ source $testdir/tester.tcl
set testprefix cursorhint
do_execsql_test 1.0 {
CREATE TABLE t1(a,b);
CREATE TABLE t2(x,y);
INSERT INTO t1 VALUES(10, 15);
INSERT INTO t1 VALUES(20, 25);
INSERT INTO t2 VALUES('ten', 'fifteen');
INSERT INTO t2 VALUES('twenty', 'twentyfive');
CREATE TABLE t1(a,b,c,d);
CREATE TABLE t2(x,y,z);
INSERT INTO t1(a,b) VALUES(10, 15);
INSERT INTO t1(a,b) VALUES(20, 25);
INSERT INTO t2(x,y) VALUES('ten', 'fifteen');
INSERT INTO t2(x,y) VALUES('twenty', 'twentyfive');
CREATE TABLE t3(id TEXT PRIMARY KEY, a, b, c, d) WITHOUT ROWID;
INSERT INTO t3(id,a,b,c,d) SELECT rowid, a, b, c, d FROM t1;
PRAGMA automatic_index = 0;
}
proc H {expr} {
lappend ::cursorhint $expr
# Run EXPLAIN on $sql. Return a list of P4 values for all $opcode
# opcodes.
#
proc p4_of_opcode {db opcode sql} {
set res {}
$db eval "EXPLAIN $sql" x {
if {$x(opcode)==$opcode} {lappend res $x(p4)}
}
return $res
}
proc do_cursorhint_test {tn sql hints} {
cursorhint_hook H
set ::cursorhint [list]
set testbody [subst {
execsql {$sql}
set ::cursorhint
}]
uplevel [list do_test $tn $testbody [list {*}$hints]]
cursorhint_hook
# Run EXPLAIN on $sql. Return a list of P5 values for all $opcode
# opcodes that contain regexp $comment in their comment
#
proc p5_of_opcode {db opcode comment sql} {
set res {}
$db eval "EXPLAIN $sql" x {
if {$x(opcode)==$opcode && [regexp $comment $x(comment)]} {
lappend res $x(p5)
}
}
return $res
}
# Verify that when t1 is in the outer loop and t2 is in the inner loop,
# no cursor hints occur for t1 (since it is a full table scan) but that
# each t2 access has a cursor hint based on the current t1.a value.
#
do_test 1.1 {
p4_of_opcode db CursorHint {
SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
}
} {/(r*==c0)/}
do_test 1.2 {
p5_of_opcode db OpenRead . {
SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
}
} {00 00}
do_cursorhint_test 1.1 {
SELECT * FROM t1 CROSS JOIN t2 WHERE a=x;
} {
{(10 == col(0))}
{(20 == col(0))}
}
# Do the same test the other way around.
#
do_test 2.1 {
p4_of_opcode db CursorHint {
SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
}
} {/(c0==r*)/}
do_test 2.2 {
p5_of_opcode db OpenRead . {
SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
}
} {00 00}
do_cursorhint_test 1.2 {
SELECT * FROM t2 CROSS JOIN t1 WHERE a=x;
} {
{(col(0) == 'ten')}
{(col(0) == 'twenty')}
}
# Various expressions captured by CursorHint
#
do_test 3.1 {
p4_of_opcode db CursorHint {
SELECT * FROM t1 WHERE a=15 AND c=22 AND rowid!=98
}
} {/(c0==15).*(c2==22).*(rowid!=98)/}
do_test 3.2 {
p4_of_opcode db CursorHint {
SELECT * FROM t3 WHERE a<15 AND b>22 AND id!=98
}
} {/(c1<15).*(c2>22).*(c0!=98)/}
do_cursorhint_test 1.3 {
SELECT * FROM t1 CROSS JOIN t2 WHERE b=15;
} {
{(col(1) == 15)}
}
do_cursorhint_test 1.3 {
SELECT * FROM t1 CROSS JOIN t2 WHERE y=b+1;
} {
{(col(1) == (15 + 1))}
{(col(1) == (25 + 1))}
}
# Indexed queries
#
do_test 4.1 {
db eval {
CREATE INDEX t1bc ON t1(b,c);
CREATE INDEX t2yz ON t2(y,z);
}
p4_of_opcode db CursorHint {
SELECT * FROM t1 WHERE b>11;
}
} {/(c0>11)/}
do_test 4.2 {
p5_of_opcode db OpenRead . {
SELECT * FROM t1 WHERE b>11;
}
} {02 00}
do_test 4.3 {
p4_of_opcode db CursorHint {
SELECT c FROM t1 WHERE b>11;
}
} {/(c0>11)/}
do_test 4.4 {
p5_of_opcode db OpenRead . {
SELECT c FROM t1 WHERE b>11;
}
} {00}
finish_test