| # 2011 March 10 |
| # |
| # 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. The |
| # focus of this file is testing the SQLITE_OMIT_UNIQUE_ENFORCEMENT |
| # compiler option. |
| # |
| |
| set testdir [file dirname $argv0] |
| source $testdir/tester.tcl |
| |
| set uniq_enforced 1 |
| ifcapable !unique_enforcement { |
| set uniq_enforced 0 |
| } |
| |
| # table with UNIQUE keyword on column |
| do_test omitunique-1.1 { |
| catchsql { CREATE TABLE t1(a TEXT UNIQUE); } |
| } {0 {}} |
| |
| # table with UNIQUE clause on column |
| do_test omitunique-1.2 { |
| catchsql { CREATE TABLE t2(a TEXT, UNIQUE(a)); } |
| } {0 {}} |
| |
| # table with UNIQUE index on column |
| do_test omitunique-1.3 { |
| catchsql { |
| CREATE TABLE t3(a TEXT); |
| CREATE UNIQUE INDEX t3a ON t3(a); |
| } |
| } {0 {}} |
| |
| # table with regular index on column |
| do_test omitunique-1.4 { |
| catchsql { |
| CREATE TABLE t4(a TEXT); |
| CREATE INDEX t4a ON t4(a); |
| } |
| } {0 {}} |
| |
| # table with no index on column |
| do_test omitunique-1.5 { |
| catchsql { CREATE TABLE t5(a TEXT); } |
| } {0 {}} |
| |
| # run our tests using several table/index forms |
| foreach {j tbl uniq cnt qp_est stat_enforce stat_omit } { |
| 1 {t1} 1 1 1 {2 1} {9 9} |
| 2 {t2} 1 1 1 {2 1} {9 9} |
| 3 {t3} 1 1 1 {2 1} {9 9} |
| 4 {t4} 0 9 10 {9 9} {9 9} |
| 5 {t5} 0 9 100000 9 9 |
| } { |
| |
| do_test omitunique-2.0.$j.1 { |
| catchsql [ subst {INSERT INTO $tbl (a) VALUES('abc'); }] |
| } {0 {}} |
| do_test omitunique-2.0.$j.2 { |
| catchsql [ subst {INSERT INTO $tbl (a) VALUES('123'); }] |
| } {0 {}} |
| |
| # check various INSERT commands |
| foreach {i cmd err} { |
| 1 {INSERT} 1 |
| 2 {INSERT OR IGNORE} 0 |
| 3 {INSERT OR REPLACE} 0 |
| 4 {REPLACE} 0 |
| 5 {INSERT OR FAIL} 1 |
| 6 {INSERT OR ABORT} 1 |
| 7 {INSERT OR ROLLBACK} 1 |
| } { |
| |
| ifcapable explain { |
| set x [execsql [ subst { EXPLAIN $cmd INTO $tbl (a) VALUES('abc'); }]] |
| ifcapable unique_enforcement { |
| do_test omitunique-2.1.$j.$i.1 { |
| regexp { IsUnique } $x |
| } $uniq |
| } |
| ifcapable !unique_enforcement { |
| do_test omitunique-2.1.$j.$i.1 { |
| regexp { IsUnique } $x |
| } {0} |
| } |
| } |
| |
| if { $uniq_enforced==0 || $uniq==0 || $err==0 } { |
| set msg {0 {}} |
| } { |
| set msg {1 {column a is not unique}} |
| } |
| do_test omitunique-2.1.$j.$i.3 { |
| catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc'); }] |
| } $msg |
| |
| } |
| # end foreach cmd |
| |
| # check UPDATE command |
| ifcapable explain { |
| set x [execsql [ subst { EXPLAIN UPDATE $tbl SET a='abc'; }]] |
| ifcapable unique_enforcement { |
| do_test omitunique-2.2.$j.1 { |
| regexp { IsUnique } $x |
| } $uniq |
| } |
| ifcapable !unique_enforcement { |
| do_test omitunique-2.2.$j.1 { |
| regexp { IsUnique } $x |
| } {0} |
| } |
| } |
| if { $uniq_enforced==0 || $uniq==0 } { |
| set msg {0 {}} |
| } { |
| set msg {1 {column a is not unique}} |
| } |
| do_test omitunique-2.2.$j.3 { |
| catchsql [ subst { UPDATE $tbl SET a='abc'; }] |
| } $msg |
| |
| # check record counts |
| do_test omitunique-2.3.$j { |
| execsql [ subst { SELECT count(*) FROM $tbl WHERE a='abc'; }] |
| } $cnt |
| |
| # make sure the query planner row estimate not affected because of omit enforcement |
| ifcapable explain { |
| do_test omitunique-2.4.$j { |
| set x [ execsql [ subst { EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc'; }]] |
| set y [ subst {~$qp_est row} ] |
| regexp $y $x |
| } {1} |
| } |
| |
| # make sure we omit extra OP_Next opcodes when the UNIQUE constraints |
| # mean there will only be a single pass through the code |
| ifcapable explain { |
| set x [execsql [ subst { EXPLAIN SELECT * FROM $tbl WHERE a='abc'; }]] |
| do_test omitunique-2.5.$j { |
| if { [ regexp { Next } $x ] } { expr { 0 } } { expr { 1 } } |
| } $uniq |
| } |
| |
| # make sure analyze index stats correct |
| ifcapable analyze { |
| if { $uniq_enforced==0 } { |
| set msg [ list $stat_omit ] |
| } { |
| set msg [ list $stat_enforce ] |
| } |
| do_test omitunique-2.6.$j { |
| execsql [ subst { ANALYZE $tbl; } ] |
| execsql [ subst { SELECT stat FROM sqlite_stat1 WHERE tbl='$tbl'; } ] |
| } $msg |
| } |
| |
| } |
| # end foreach tbl |
| |
| finish_test |