Index: third_party/sqlite/src/test/sort.test |
diff --git a/third_party/sqlite/src/test/sort.test b/third_party/sqlite/src/test/sort.test |
index 08d496b2596a0380455034930d974f4e20a816c2..be2a6f531c05826cf85fbd1f60044ca62f9d0650 100644 |
--- a/third_party/sqlite/src/test/sort.test |
+++ b/third_party/sqlite/src/test/sort.test |
@@ -8,13 +8,14 @@ |
# May you share freely, never taking more than you give. |
# |
#*********************************************************************** |
+# |
# This file implements regression tests for SQLite library. The |
-# focus of this file is testing the CREATE TABLE statement. |
+# focus of this file is testing the sorter (code in vdbesort.c). |
# |
-# $Id: sort.test,v 1.25 2005/11/14 22:29:06 drh Exp $ |
set testdir [file dirname $argv0] |
source $testdir/tester.tcl |
+set testprefix sort |
# Create a bunch of data to sort against |
# |
@@ -464,4 +465,175 @@ do_test sort-12.1 { |
} |
} {1 2 xxx 1 3 yyy 1 1 zzz} |
+#------------------------------------------------------------------------- |
+# Check that the sorter in vdbesort.c sorts in a stable fashion. |
+# |
+do_execsql_test sort-13.0 { |
+ CREATE TABLE t10(a, b); |
+} |
+do_test sort-13.1 { |
+ db transaction { |
+ for {set i 0} {$i < 100000} {incr i} { |
+ execsql { INSERT INTO t10 VALUES( $i/10, $i%10 ) } |
+ } |
+ } |
+} {} |
+do_execsql_test sort-13.2 { |
+ SELECT a, b FROM t10 ORDER BY a; |
+} [db eval {SELECT a, b FROM t10 ORDER BY a, b}] |
+do_execsql_test sort-13.3 { |
+ PRAGMA cache_size = 5; |
+ SELECT a, b FROM t10 ORDER BY a; |
+} [db eval {SELECT a, b FROM t10 ORDER BY a, b}] |
+ |
+#------------------------------------------------------------------------- |
+# Sort some large ( > 4KiB) records. |
+# |
+proc cksum {x} { |
+ set i1 1 |
+ set i2 2 |
+ binary scan $x c* L |
+ foreach {a b} $L { |
+ set i1 [expr (($i2<<3) + $a) & 0x7FFFFFFF] |
+ set i2 [expr (($i1<<3) + $b) & 0x7FFFFFFF] |
+ } |
+ list $i1 $i2 |
+} |
+db func cksum cksum |
+ |
+do_execsql_test sort-14.0 { |
+ PRAGMA cache_size = 5; |
+ CREATE TABLE t11(a, b); |
+ INSERT INTO t11 VALUES(randomblob(5000), NULL); |
+ INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --2 |
+ INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --3 |
+ INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --4 |
+ INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --5 |
+ INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --6 |
+ INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --7 |
+ INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --8 |
+ INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --9 |
+ UPDATE t11 SET b = cksum(a); |
+} |
+ |
+foreach {tn mmap_limit} { |
+ 1 0 |
+ 2 1000000 |
+} { |
+ do_test sort-14.$tn { |
+ sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $mmap_limit |
+ set prev "" |
+ db eval { SELECT * FROM t11 ORDER BY b } { |
+ if {$b != [cksum $a]} {error "checksum failed"} |
+ if {[string compare $b $prev] < 0} {error "sort failed"} |
+ set prev $b |
+ } |
+ set {} {} |
+ } {} |
+} |
+ |
+#------------------------------------------------------------------------- |
+# |
+foreach {tn mmap_limit nWorker tmpstore coremutex fakeheap softheaplimit} { |
+ 1 0 3 file true false 0 |
+ 2 0 3 file true true 0 |
+ 3 0 0 file true false 0 |
+ 4 1000000 3 file true false 0 |
+ 5 0 0 memory false true 0 |
+ 6 0 0 file false true 1000000 |
+ 7 0 0 file false true 10000 |
+} { |
+ db close |
+ sqlite3_shutdown |
+ if {$coremutex} { |
+ sqlite3_config multithread |
+ } else { |
+ sqlite3_config singlethread |
+ } |
+ sqlite3_initialize |
+ sorter_test_fakeheap $fakeheap |
+ sqlite3_soft_heap_limit $softheaplimit |
+ |
+ reset_db |
+ sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $mmap_limit |
+ execsql "PRAGMA temp_store = $tmpstore; PRAGMA threads = $nWorker" |
+ |
+ |
+ set ten [string repeat X 10300] |
+ set one [string repeat y 200] |
+ |
+ if {$softheaplimit} { |
+ execsql { PRAGMA cache_size = 20 }; |
+ } else { |
+ execsql { PRAGMA cache_size = 5 }; |
+ } |
+ |
+ do_execsql_test 15.$tn.1 { |
+ WITH rr AS ( |
+ SELECT 4, $ten UNION ALL |
+ SELECT 2, $one UNION ALL |
+ SELECT 1, $ten UNION ALL |
+ SELECT 3, $one |
+ ) |
+ SELECT * FROM rr ORDER BY 1; |
+ } [list 1 $ten 2 $one 3 $one 4 $ten] |
+ |
+ do_execsql_test 15.$tn.2 { |
+ CREATE TABLE t1(a); |
+ INSERT INTO t1 VALUES(4); |
+ INSERT INTO t1 VALUES(5); |
+ INSERT INTO t1 VALUES(3); |
+ INSERT INTO t1 VALUES(2); |
+ INSERT INTO t1 VALUES(6); |
+ INSERT INTO t1 VALUES(1); |
+ CREATE INDEX i1 ON t1(a); |
+ SELECT * FROM t1 ORDER BY a; |
+ } {1 2 3 4 5 6} |
+ |
+ do_execsql_test 15.$tn.3 { |
+ WITH rr AS ( |
+ SELECT 4, $ten UNION ALL |
+ SELECT 2, $one |
+ ) |
+ SELECT * FROM rr ORDER BY 1; |
+ } [list 2 $one 4 $ten] |
+ |
+ sorter_test_fakeheap 0 |
+} |
+ |
+db close |
+sqlite3_shutdown |
+set t(0) singlethread |
+set t(1) multithread |
+set t(2) serialized |
+sqlite3_config $t($sqlite_options(threadsafe)) |
+sqlite3_initialize |
+sqlite3_soft_heap_limit 0 |
+ |
+reset_db |
+do_catchsql_test 16.1 { |
+ CREATE TABLE t1(a, b, c); |
+ INSERT INTO t1 VALUES(1, 2, 3); |
+ INSERT INTO t1 VALUES(1, NULL, 3); |
+ INSERT INTO t1 VALUES(NULL, 2, 3); |
+ INSERT INTO t1 VALUES(1, 2, NULL); |
+ INSERT INTO t1 VALUES(4, 5, 6); |
+ CREATE UNIQUE INDEX i1 ON t1(b, a, c); |
+} {0 {}} |
+reset_db |
+do_catchsql_test 16.2 { |
+ CREATE TABLE t1(a, b, c); |
+ INSERT INTO t1 VALUES(1, 2, 3); |
+ INSERT INTO t1 VALUES(1, NULL, 3); |
+ INSERT INTO t1 VALUES(1, 2, 3); |
+ INSERT INTO t1 VALUES(1, 2, NULL); |
+ INSERT INTO t1 VALUES(4, 5, 6); |
+ CREATE UNIQUE INDEX i1 ON t1(b, a, c); |
+} {1 {UNIQUE constraint failed: t1.b, t1.a, t1.c}} |
+ |
+reset_db |
+do_execsql_test 17.1 { |
+ SELECT * FROM sqlite_master ORDER BY sql; |
+} {} |
+ |
finish_test |