sqlite/test/omitunique.test

171 lines
4.3 KiB
Plaintext

# 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