From: drh Date: Sat, 24 Feb 2007 15:18:49 +0000 (+0000) Subject: Additional test cases added. Improvements to the INSERT transfer X-Git-Tag: version-3.6.10~2508 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fb658dedce94cc9df06cda5127f6c616a01d4403;p=thirdparty%2Fsqlite.git Additional test cases added. Improvements to the INSERT transfer optimization. (CVS 3662) FossilOrigin-Name: 2bf5475bde763f73f7f4dd9cac7d13a631a7d2aa --- diff --git a/manifest b/manifest index 74cde5beda..8b0f379f92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 +C Additional\stest\scases\sadded.\s\sImprovements\sto\sthe\sINSERT\stransfer\noptimization.\s(CVS\s3662) +D 2007-02-24T15:18:50 F Makefile.in 1fe3d0b46e40fd684e1e61f8e8056cefed16de9f F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -69,7 +69,7 @@ F src/expr.c 3fc187bc438f5637332b2a01b1bf6f728cf2830c F src/func.c b7e1e220a6795ecae7649815145ea5f8644dfa5f F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 -F src/insert.c e0a6288f429b9a387b5f15bd8d1fab33da6071ae +F src/insert.c 72cb64b698796f2005c0158e098124d9490868bb F src/legacy.c 2631df6a861f830d6b1c0fe92b9fdd745b2c0cd6 F src/loadext.c bbfdbf452c71b6f2723375478a365788498ec3cd F src/main.c 33c32014da3a1471e8869d2eba32b2c4314c39ce @@ -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 319455dcc650f6d0182b6e30fe8fa02c992fa61d +F test/insert4.test 0bb119fea2868afdcf78e4e3e3bfed27bbdb2430 F test/interrupt.test c38b7f7c17914f0cd6a119beed5d03bc3f47f9eb F test/intpkey.test af4fd826c4784ec5c93b444de07adea0254d0d30 F test/ioerr.test 565f1a47c6af6bb75dc0ff633213cec63470c19c @@ -326,6 +326,7 @@ F test/tkt1873.test 7159a1c1bf627bbb03f11362e4ad4de11d6ff316 F test/tkt2141.test 78fb8ea2e7e38f7e5b3e649ca9426928056ef55c F test/tkt2192.test 480d0e017ddb01a46ee20809427370f343bb3c03 F test/tkt2213.test 8cf7c446e1fcd0627fffe7fc19046eb24ac7333b +F test/tkt2251.test 3f0549213386ed911715665a908ff2bb7a871002 F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567 F test/trans.test 06bff0246886858793fca3748721936e2f65e3df F test/trigger1.test 2c79e2bf76350811e362814e98779c120b6a9421 @@ -433,7 +434,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 6fc18275230563437f2985eac3795e4dfe8eb9de -R dc1288c66501ac9293e7f7ec0f6a9fa4 +P 830985814345f71ba2def3c206e36aabe9e1ee7c +R 05e26f17eb8b96bb85b027f957e8b674 U drh -Z 2773dc4bcb469b493e92a530de53d946 +Z 43981f64256c87de6c82c0452ce773e2 diff --git a/manifest.uuid b/manifest.uuid index a416f8abbf..9b1f56a3b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -830985814345f71ba2def3c206e36aabe9e1ee7c \ No newline at end of file +2bf5475bde763f73f7f4dd9cac7d13a631a7d2aa \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 84853d980d..8b0f76bead 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.175 2007/02/24 13:53:05 drh Exp $ +** $Id: insert.c,v 1.176 2007/02/24 15:18:50 drh Exp $ */ #include "sqliteInt.h" @@ -1462,7 +1462,7 @@ static int xferOptimization( return 0; /* pDestIdx has no corresponding index in pSrc */ } } - if( !sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){ + if( pDest->pCheck && !sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } diff --git a/test/insert4.test b/test/insert4.test index 22d88e7a47..56e23da16a 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT transfer optimization. # -# $Id: insert4.test,v 1.2 2007/02/24 13:53:05 drh Exp $ +# $Id: insert4.test,v 1.3 2007/02/24 15:18:50 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -26,14 +26,23 @@ proc xferopt_test {testname N} { do_test $testname {set ::sqlite3_xferopt_count} $N } +# Create tables used for testing. +# +execsql { + CREATE TABLE t1(a int, b int, check(b>a)); + CREATE TABLE t2(x int, y int); + CREATE VIEW v2 AS SELECT y, x FROM t2; + CREATE TABLE t3(a int, b int); +} + # 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); + DELETE FROM t1; + DELETE FROM t2; INSERT INTO t2 VALUES(9,1); } catchsql { @@ -53,6 +62,7 @@ do_test insert4-1.3 { # The SELECT must be against a real table. do_test insert4-2.1.1 { execsql { + DELETE FROM t1; INSERT INTO t1 SELECT 4, 8; SELECT * FROM t1; } @@ -61,8 +71,7 @@ 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; + INSERT INTO t1 SELECT * FROM v2; SELECT * FROM t1; } } {0 {1 9}} @@ -72,7 +81,8 @@ xferopt_test insert4-2.2.2 0 # do_test insert4-2.3.1 { execsql { - CREATE TABLE t3(a int, b int); + DELETE FROM t2; + INSERT INTO t2 VALUES(9,1); INSERT INTO t2 SELECT y, x FROM t2; INSERT INTO t3 SELECT * FROM t2 LIMIT 1; SELECT * FROM t3; @@ -106,19 +116,115 @@ do_test insert4-2.4.3 { } {1 {constraint failed}} xferopt_test insert4-2.4.4 0 -# Do run the transfer optimization if tables have identical -# CHECK constraints. +# The following procedure constructs two tables then tries to transfer +# data from one table to the other. Checks are made to make sure the +# transfer is successful and that the transfer optimization was used or +# not, as appropriate. # -do_test insert4-3.1.1 { - set sqlite3_xferopt_count 0 +# xfer_check TESTID XFER-USED INIT-DATA DEST-SCHEMA SRC-SCHEMA +# +# The TESTID argument is the symbolic name for this test. The XFER-USED +# argument is true if the transfer optimization should be employed and +# false if not. INIT-DATA is a single row of data that is to be +# transfered. DEST-SCHEMA and SRC-SCHEMA are table declarations for +# the destination and source tables. +# +proc xfer_check {testid xferused initdata destschema srcschema} { + execsql "CREATE TABLE dest($destschema)" + execsql "CREATE TABLE src($srcschema)" + execsql "INSERT INTO src VALUES([join $initdata ,])" + set ::sqlite3_xferopt_count 0 + do_test $testid.1 { + execsql { + INSERT INTO dest SELECT * FROM src; + SELECT * FROM dest; + } + } $initdata + do_test $testid.2 { + set ::sqlite3_xferopt_count + } $xferused 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; + DROP TABLE dest; + DROP TABLE src; } -} {1 9} -xferopt_test insert4-3.1.2 1 +} + + +# Do run the transfer optimization if tables have identical +# CHECK constraints. +# +xfer_check insert4-3.1 1 {1 9} \ + {a int, b int CHECK(b>a)} \ + {x int, y int CHECK(y>x)} +xfer_check insert4-3.2 1 {1 9} \ + {a int, b int CHECK(b>a)} \ + {x int CHECK(y>x), y int} + +# Do run the transfer optimization if the destination table lacks +# any CHECK constraints regardless of whether or not there are CHECK +# constraints on the source table. +# +xfer_check insert4-3.3 1 {1 9} \ + {a int, b int} \ + {x int, y int CHECK(y>x)} + +# Do run the transfer optimization if the destination table omits +# NOT NULL constraints that the source table has. +# +xfer_check insert4-3.4 0 {1 9} \ + {a int, b int CHECK(b>a)} \ + {x int, y int} + +# Do not run the optimization if the destination has NOT NULL +# constraints that the source table lacks. +# +xfer_check insert4-3.5 0 {1 9} \ + {a int, b int NOT NULL} \ + {x int, y int} +xfer_check insert4-3.6 0 {1 9} \ + {a int, b int NOT NULL} \ + {x int NOT NULL, y int} +xfer_check insert4-3.7 0 {1 9} \ + {a int NOT NULL, b int NOT NULL} \ + {x int NOT NULL, y int} +xfer_check insert4-3.8 0 {1 9} \ + {a int NOT NULL, b int} \ + {x int, y int} + + +# Do run the transfer optimization if the destination table and +# source table have the same NOT NULL constraints or if the +# source table has extra NOT NULL constraints. +# +xfer_check insert4-3.9 1 {1 9} \ + {a int, b int} \ + {x int NOT NULL, y int} +xfer_check insert4-3.10 1 {1 9} \ + {a int, b int} \ + {x int NOT NULL, y int NOT NULL} +xfer_check insert4-3.11 1 {1 9} \ + {a int NOT NULL, b int} \ + {x int NOT NULL, y int NOT NULL} +xfer_check insert4-3.12 1 {1 9} \ + {a int, b int NOT NULL} \ + {x int NOT NULL, y int NOT NULL} + +# Do not run the optimization if any corresponding table +# columns have different affinities. +# +xfer_check insert4-3.20 0 {1 9} \ + {a text, b int} \ + {x int, b int} +xfer_check insert4-3.21 0 {1 9} \ + {a int, b int} \ + {x text, b int} + +# "int" and "integer" are equivalent so the optimization should +# run here. +# +xfer_check insert4-3.22 1 {1 9} \ + {a int, b int} \ + {x integer, b int} + finish_test diff --git a/test/tkt2251.test b/test/tkt2251.test new file mode 100644 index 0000000000..633132f999 --- /dev/null +++ b/test/tkt2251.test @@ -0,0 +1,103 @@ +# 2007 Febuary 24 +# +# 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. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests to verify that table column values +# are pulled out of the database correctly. +# +# Long ago, the OP_Column opcode was sufficient to pull out the +# value of a table column. But then we added the ALTER TABLE ADD COLUMN +# feature. An added column might not actually exist in every row, +# and so the OP_Column opcode has to contain a default value. Later +# still we added a feature whereby a REAL value with no fractional +# part is stored in the database file as an integer to save space. +# After extracting the value, we have to call OP_RealAffinity to +# convert it back to a REAL. +# +# The sqlite3ExprCodeGetColumn() routine was added to take care of +# all of the complications above. The tests in this file attempt +# to verify that sqlite3ExprCodeGetColumn() is used instead of a +# raw OP_Column in all places where a table column is extracted from +# the database. +# +# $Id: tkt2251.test,v 1.1 2007/02/24 15:18:51 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Create sample data. Verify that the default value and type of an added +# column is correct for aggregates. +do_test tkt2251-1.1 { + execsql { + CREATE TABLE t1(a INTEGER); + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); + INSERT INTO t1 VALUES(9); + INSERT INTO t1 VALUES(9); + INSERT INTO t1 VALUES(9); + INSERT INTO t1 VALUES(3); + INSERT INTO t1 VALUES(2); + ALTER TABLE t1 ADD COLUMN b REAL DEFAULT 4.0; + SELECT avg(b), typeof(avg(b)) FROM t1; + } +} {4.0 real} +do_test tkt2251-1.2 { + execsql { + SELECT sum(b), typeof(sum(b)) FROM t1; + } +} {32.0 real} +do_test tkt2251-1.3 { + execsql { + SELECT a, sum(b), typeof(sum(b)) FROM t1 GROUP BY a ORDER BY a; + } +} {1 8.0 real 2 8.0 real 3 4.0 real 9 12.0 real} + +# Make sure that the REAL value comes out when values are accessed +# by index. +# +do_test tkt2251-2.1 { + execsql { + SELECT b, typeof(b) FROM t1 WHERE a=3; + } +} {4.0 real} +do_test tkt2251-2.2 { + execsql { + CREATE INDEX t1i1 ON t1(a,b); + SELECT b, typeof(b) FROM t1 WHERE a=3; + } +} {4.0 real} +do_test tkt2251-2.3 { + execsql { + REINDEX; + SELECT b, typeof(b) FROM t1 WHERE a=3; + } +} {4.0 real} + +# Make sure the correct REAL value is used when copying from one +# table to another. +# +do_test tkt2251-3.1 { + execsql { + CREATE TABLE t2(x,y); + INSERT INTO t2 SELECT * FROM t1; + SELECT y, typeof(y) FROM t2 WHERE x=3; + } +} {4.0 real} +do_test tkt2251-3.2 { + execsql { + CREATE TABLE t3 AS SELECT * FROM t1; + SELECT b, typeof(b) FROM t3 WHERE a=3; + } +} {4.0 real} + + +finish_test