From dd73521bc26ccd24bc8652f672c74c2fcdc6f0f4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 24 Feb 2007 13:53:05 +0000 Subject: [PATCH] Additional tests and some improvements to the INSERT transfer optimization. More testing is needed. (CVS 3661) FossilOrigin-Name: 830985814345f71ba2def3c206e36aabe9e1ee7c --- manifest | 18 ++++++------- manifest.uuid | 2 +- src/expr.c | 4 +-- src/insert.c | 15 ++++++++++- src/test1.c | 5 +++- test/insert4.test | 65 +++++++++++++++++++++++++++++++++++++++++------ 6 files changed, 87 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 7a40efb515..74cde5beda 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sINSERT\sxfer\soptimization\sdoes\snot\strigger\sif\sthe\sCHECK\nconstraints\son\sthe\stwo\stables\sare\snot\sidentical.\s\sTicket\s#2252.\s(CVS\s3660) -D 2007-02-24T13:23:52 +C Additional\stests\sand\ssome\simprovements\sto\sthe\sINSERT\stransfer\noptimization.\s\sMore\stesting\sis\sneeded.\s(CVS\s3661) +D 2007-02-24T13:53:05 F Makefile.in 1fe3d0b46e40fd684e1e61f8e8056cefed16de9f F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -65,11 +65,11 @@ F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675 F src/date.c 393c73fc027597e008dcd81454544659e978b05c F src/delete.c 151d08386bf9c9e7f92f6b9106c71efec2def184 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b -F src/expr.c 7815bdb27152e0b9025a089608403f7fa5d279ec +F src/expr.c 3fc187bc438f5637332b2a01b1bf6f728cf2830c F src/func.c b7e1e220a6795ecae7649815145ea5f8644dfa5f F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 -F src/insert.c e1398c4167299704b30a037bbab6194137f34049 +F src/insert.c e0a6288f429b9a387b5f15bd8d1fab33da6071ae F src/legacy.c 2631df6a861f830d6b1c0fe92b9fdd745b2c0cd6 F src/loadext.c bbfdbf452c71b6f2723375478a365788498ec3cd F src/main.c 33c32014da3a1471e8869d2eba32b2c4314c39ce @@ -100,7 +100,7 @@ F src/sqlite3ext.h 011c75fd6459a61454514af07c7a4f1f5c767f27 F src/sqliteInt.h cc9f729ca211a11a9d735b66a5f6c968a143e472 F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06 F src/tclsqlite.c cd2b3b86ab07c0e0779f6c6e71e72c6c7dc1e704 -F src/test1.c cb314bfa3e9251b545fa3669ec80a8c8a0a86310 +F src/test1.c b4ff8f82f84d2ccdf07a2db5acae7b47c12f60d7 F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b F src/test3.c ed494a126221c4b9f66f8f0445554ad749764709 F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25 @@ -228,7 +228,7 @@ F test/index3.test f66718cd92ce1216819d47e6a156755e4b2c4ca1 F test/insert.test 42e26d9192f36859938765e6817fb957cf19532b F test/insert2.test 5a20e1ace5fa0800b58d28284212290189b49aed F test/insert3.test 09a532d5b6f3a788d91be0d4d368462f522685d1 -F test/insert4.test d733a33437657cc31d65b70249e46f464f886a4a +F test/insert4.test 319455dcc650f6d0182b6e30fe8fa02c992fa61d F test/interrupt.test c38b7f7c17914f0cd6a119beed5d03bc3f47f9eb F test/intpkey.test af4fd826c4784ec5c93b444de07adea0254d0d30 F test/ioerr.test 565f1a47c6af6bb75dc0ff633213cec63470c19c @@ -433,7 +433,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P e11bbf174c5a2fa75e3d1dd450c8b2a18f40e4da -R 0e22889d42f0395ba317d6639c075c27 +P 6fc18275230563437f2985eac3795e4dfe8eb9de +R dc1288c66501ac9293e7f7ec0f6a9fa4 U drh -Z da32718baf840d5b2e61d121b53eedac +Z 2773dc4bcb469b493e92a530de53d946 diff --git a/manifest.uuid b/manifest.uuid index c233047935..a416f8abbf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fc18275230563437f2985eac3795e4dfe8eb9de \ No newline at end of file +830985814345f71ba2def3c206e36aabe9e1ee7c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index d0b858efd6..39cb06585c 100644 --- a/src/expr.c +++ b/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.278 2007/02/24 11:52:53 drh Exp $ +** $Id: expr.c,v 1.279 2007/02/24 13:53:05 drh Exp $ */ #include "sqliteInt.h" #include @@ -2210,7 +2210,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ } if( pA->pSelect || pB->pSelect ) return 0; if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0; - if( pA->token.z ){ + if( pA->op!=TK_COLUMN && pA->token.z ){ if( pB->token.z==0 ) return 0; if( pB->token.n!=pA->token.n ) return 0; if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){ diff --git a/src/insert.c b/src/insert.c index 6823a72cb9..84853d980d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.174 2007/02/24 13:23:52 drh Exp $ +** $Id: insert.c,v 1.175 2007/02/24 13:53:05 drh Exp $ */ #include "sqliteInt.h" @@ -1297,6 +1297,16 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ return 1; } +#ifdef SQLITE_TEST +/* +** The following global variable is incremented whenever the +** transfer optimization is used. This is used for testing +** purposes only - to make sure the transfer optimization really +** is happening when it is suppose to. +*/ +int sqlite3_xferopt_count; +#endif /* SQLITE_TEST */ + /* ** Attempt the transfer optimization on INSERTs of the form ** @@ -1464,6 +1474,9 @@ static int xferOptimization( ** * We can conditionally do the transfer if the destination ** table is empty. */ +#ifdef SQLITE_TEST + sqlite3_xferopt_count++; +#endif iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema); v = sqlite3GetVdbe(pParse); iSrc = pParse->nTab++; diff --git a/src/test1.c b/src/test1.c index ac0de15c6e..108de7a640 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.228 2007/02/05 14:21:48 danielk1977 Exp $ +** $Id: test1.c,v 1.229 2007/02/24 13:53:05 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -4224,6 +4224,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite3_memMax; extern int sqlite3_like_count; extern int sqlite3_tsd_count; + extern int sqlite3_xferopt_count; #if OS_UNIX && defined(SQLITE_TEST) && defined(THREADSAFE) && THREADSAFE extern int threadsOverrideEachOthersLocks; #endif @@ -4261,6 +4262,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ (char*)&sqlite3_os_trace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite3_tsd_count", (char*)&sqlite3_tsd_count, TCL_LINK_INT); + Tcl_LinkVar(interp, "sqlite3_xferopt_count", + (char*)&sqlite3_xferopt_count, TCL_LINK_INT); #ifndef SQLITE_OMIT_UTF16 Tcl_LinkVar(interp, "unaligned_string_counter", (char*)&unaligned_string_counter, TCL_LINK_INT); diff --git a/test/insert4.test b/test/insert4.test index 8ae891e4b6..22d88e7a47 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -9,17 +9,28 @@ # #*********************************************************************** # This file implements regression tests for SQLite library. The -# focus of this file is testing corner cases of the INSERT statement. +# focus of this file is testing the INSERT transfer optimization. # -# $Id: insert4.test,v 1.1 2007/02/24 13:23:53 drh Exp $ +# $Id: insert4.test,v 1.2 2007/02/24 13:53:05 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl +# The sqlite3_xferopt_count variable is incremented whenever the +# insert transfer optimization applies. +# +# This procedure runs a test to see if the sqlite3_xferopt_count is +# set to N. +# +proc xferopt_test {testname N} { + do_test $testname {set ::sqlite3_xferopt_count} $N +} + # Ticket #2252. Make sure the an INSERT from identical tables # does not violate constraints. # do_test insert4-1.1 { + set sqlite3_xferopt_count 0 execsql { CREATE TABLE t1(a int, b int, check(b>a)); CREATE TABLE t2(x int, y int); @@ -29,21 +40,37 @@ do_test insert4-1.1 { INSERT INTO t1 SELECT * FROM t2; } } {1 {constraint failed}} -do_test insert4-1.2 { +xferopt_test insert4-1.2 0 +do_test insert4-1.3 { execsql { SELECT * FROM t1; } } {} -# Other coverage tests for the INSERT transfer optimization. +# Tests to make sure that the transfer optimization is not occurring +# when it is not a valid optimization. # -do_test insert4-2.1 { +# The SELECT must be against a real table. +do_test insert4-2.1.1 { execsql { INSERT INTO t1 SELECT 4, 8; SELECT * FROM t1; } } {4 8} +xferopt_test insert4-2.1.2 0 do_test insert4-2.2.1 { + catchsql { + DELETE FROM t1; + CREATE VIEW v1 AS SELECT y, x FROM t2; + INSERT INTO t1 SELECT * FROM v1; + SELECT * FROM t1; + } +} {0 {1 9}} +xferopt_test insert4-2.2.2 0 + +# Do not run the transfer optimization if there is a LIMIT clause +# +do_test insert4-2.3.1 { execsql { CREATE TABLE t3(a int, b int); INSERT INTO t2 SELECT y, x FROM t2; @@ -51,25 +78,47 @@ do_test insert4-2.2.1 { SELECT * FROM t3; } } {9 1} -do_test insert4-2.2.2 { +xferopt_test insert4-2.3.2 0 +do_test insert4-2.3.3 { catchsql { DELETE FROM t1; INSERT INTO t1 SELECT * FROM t2 LIMIT 1; SELECT * FROM t1; } } {1 {constraint failed}} -do_test insert4-2.3.1 { +xferopt_test insert4-2.3.4 0 + +# Do not run the transfer optimization if there is a DISTINCT +# +do_test insert4-2.4.1 { execsql { DELETE FROM t3; INSERT INTO t3 SELECT DISTINCT * FROM t2; SELECT * FROM t3; } } {9 1 1 9} -do_test insert4-2.3.2 { +xferopt_test insert4-2.4.2 0 +do_test insert4-2.4.3 { catchsql { DELETE FROM t1; INSERT INTO t1 SELECT DISTINCT * FROM t2; } } {1 {constraint failed}} +xferopt_test insert4-2.4.4 0 + +# Do run the transfer optimization if tables have identical +# CHECK constraints. +# +do_test insert4-3.1.1 { + set sqlite3_xferopt_count 0 + execsql { + DELETE FROM t1; + INSERT INTO t1 VALUES(1,9); + CREATE TABLE t4(m int, n int, CHECK(n>m)); + INSERT INTO t4 SELECT * FROM t1; + SELECT * FROM t4; + } +} {1 9} +xferopt_test insert4-3.1.2 1 finish_test