are off by one or two ULPs. Change the name of the eiib1.test test module to expridx1.test. FossilOrigin-Name: 4e996c183ea8d270b4448b471d4d032e13cef89f537674599d1e7c367cc2d0f8
274 lines
7.5 KiB
Plaintext
274 lines
7.5 KiB
Plaintext
# 2026-03-16
|
|
#
|
|
# 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 contains test cases for handling stale expression indexes -
|
|
# expression indexes for which the value of the expression is different
|
|
# from (though usually very close to) the value stored on disk.
|
|
#
|
|
set testdir [file dirname $argv0]
|
|
source $testdir/tester.tcl
|
|
set testprefix expridx1
|
|
|
|
# Check that OP_IdxDelete works when:
|
|
#
|
|
# 1.1.* The real value in the index is greater than that in the table,
|
|
# 1.2.* The real value in the index is smaller than that in the table,
|
|
# 1.3.* Duplicate distorted real values.
|
|
#
|
|
|
|
do_execsql_test 1.0.1 {
|
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL);
|
|
INSERT INTO t1 VALUES(10, 10.0);
|
|
INSERT INTO t1 VALUES(15, 15.0);
|
|
INSERT INTO t1 VALUES(20, 20.0);
|
|
INSERT INTO t1 VALUES(25, 25.0);
|
|
INSERT INTO t1 VALUES(30, 30.0);
|
|
CREATE INDEX i1 ON t1((b+0.0));
|
|
}
|
|
|
|
# Return a list of rowids from table t1 for which there is no exact
|
|
# match in the index.
|
|
set idxcheck {
|
|
SELECT rowid FROM t1 AS o NOT INDEXED
|
|
WHERE NOT EXISTS (SELECT 1 FROM t1 WHERE +a=o.a AND b+0.0=o.b+0.0)
|
|
}
|
|
|
|
set root [db one {SELECT rootpage FROM sqlite_schema WHERE name='i1'}]
|
|
|
|
do_test 1.0.2 {
|
|
# Create an imposter table for index i1
|
|
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $root
|
|
db eval {
|
|
CREATE TABLE x1(b, rowid, PRIMARY KEY(b, rowid)) WITHOUT ROWID;
|
|
}
|
|
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0
|
|
|
|
db one { PRAGMA integrity_check }
|
|
} ok
|
|
|
|
do_execsql_test 1.1.1 {
|
|
UPDATE x1 SET b=21.0 WHERE rowid=20;
|
|
}
|
|
do_execsql_test 1.1.1b {
|
|
PRAGMA integrity_check;
|
|
} {{row 3 missing from index i1}}
|
|
do_execsql_test 1.1.1c $idxcheck {20}
|
|
|
|
do_execsql_test 1.1.2 {
|
|
DELETE FROM t1 WHERE a=20;
|
|
} {}
|
|
do_execsql_test 1.1.3 {
|
|
PRAGMA integrity_check;
|
|
} {ok}
|
|
do_execsql_test 1.1.4 $idxcheck {}
|
|
|
|
do_execsql_test 1.2.1 {
|
|
UPDATE x1 SET b=26.0 WHERE rowid=25;
|
|
PRAGMA integrity_check;
|
|
} {
|
|
{row 3 missing from index i1}
|
|
}
|
|
do_execsql_test 1.2.2 $idxcheck {25}
|
|
|
|
do_execsql_test 1.2.3 {
|
|
DELETE FROM t1 WHERE a=25;
|
|
} {}
|
|
do_execsql_test 1.2.4 {
|
|
PRAGMA integrity_check;
|
|
} {ok}
|
|
do_execsql_test 1.2.5 $idxcheck {}
|
|
|
|
do_execsql_test 1.3.1 {
|
|
DELETE FROM t1;
|
|
INSERT INTO t1 VALUES(5, 15.0);
|
|
INSERT INTO t1 VALUES(10, 20.0);
|
|
INSERT INTO t1 VALUES(15, 20.0);
|
|
INSERT INTO t1 VALUES(20, 20.0);
|
|
INSERT INTO t1 VALUES(25, 20.0);
|
|
INSERT INTO t1 VALUES(30, 20.0);
|
|
INSERT INTO t1 VALUES(35, 25.0);
|
|
|
|
UPDATE x1 SET b=19.0 WHERE b=20.0;
|
|
PRAGMA integrity_check;
|
|
} {
|
|
{row 2 missing from index i1}
|
|
{row 3 missing from index i1}
|
|
{row 4 missing from index i1}
|
|
{row 5 missing from index i1}
|
|
{row 6 missing from index i1}
|
|
}
|
|
|
|
do_execsql_test 1.3.2 $idxcheck {10 15 20 25 30}
|
|
|
|
foreach {tn a} {
|
|
1 15 2 30 3 20 4 10 5 25
|
|
} {
|
|
do_execsql_test 1.3.3.$tn {
|
|
DELETE FROM t1 WHERE a=$a
|
|
}
|
|
}
|
|
do_execsql_test 1.3.4 {
|
|
PRAGMA integrity_check
|
|
} {ok}
|
|
do_execsql_test 1.3.5 $idxcheck {}
|
|
|
|
#-------------------------------------------------------------------------
|
|
reset_db
|
|
set nRow [expr 1000]
|
|
do_execsql_test 2.0 {
|
|
CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)) WITHOUT ROWID;
|
|
WITH s(i) AS (
|
|
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<$nRow
|
|
)
|
|
INSERT INTO t1 SELECT i, random(), hex(randomblob(50)) FROM s;
|
|
CREATE INDEX t1c ON t1(+c);
|
|
}
|
|
|
|
set idxcheck {
|
|
SELECT a, b FROM t1 AS o NOT INDEXED
|
|
WHERE NOT EXISTS (SELECT 1 FROM t1 WHERE +a=o.a AND +b=o.b AND +c=o.c)
|
|
}
|
|
|
|
set root [db one {SELECT rootpage FROM sqlite_schema WHERE name='t1c'}]
|
|
|
|
do_test 2.1 {
|
|
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $root
|
|
db eval {
|
|
CREATE TABLE x1(a, b, c, PRIMARY KEY(c, a, b)) WITHOUT ROWID;
|
|
}
|
|
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0
|
|
} {}
|
|
|
|
do_execsql_test 2.2 {
|
|
UPDATE x1 SET c=hex(randomblob(50)) WHERE (a%2)!=0
|
|
}
|
|
|
|
do_execsql_test 2.3 "
|
|
SELECT count(*) FROM ( $idxcheck )
|
|
" [expr $nRow/2]
|
|
|
|
do_test 2.4 {
|
|
for {set ii 1} {$ii<$nRow} {incr ii 2} {
|
|
execsql { DELETE FROM t1 WHERE a=$ii }
|
|
}
|
|
execsql {PRAGMA integrity_check}
|
|
} {ok}
|
|
|
|
do_execsql_test 2.5 "
|
|
SELECT count(*) FROM ( $idxcheck )
|
|
" 0
|
|
|
|
#-------------------------------------------------------------------------
|
|
reset_db
|
|
do_execsql_test 3.0 {
|
|
CREATE TABLE y1(a, b, c GENERATED ALWAYS AS (a*b) VIRTUAL);
|
|
CREATE INDEX i1 ON y1(c);
|
|
INSERT INTO y1 VALUES(2, 3);
|
|
INSERT INTO y1 VALUES(4, 5);
|
|
}
|
|
|
|
set idxcheck {
|
|
SELECT rowid FROM y1 AS o NOT INDEXED
|
|
WHERE NOT EXISTS (SELECT 1 FROM y1 WHERE +rowid=o.rowid AND c=o.c)
|
|
}
|
|
|
|
set root [db one {SELECT rootpage FROM sqlite_schema WHERE name='i1'}]
|
|
|
|
do_test 3.1 {
|
|
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $root
|
|
db eval { CREATE TABLE x1(c, rowid, PRIMARY KEY(c, rowid)) WITHOUT ROWID; }
|
|
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0
|
|
} {}
|
|
|
|
do_execsql_test 3.2 {
|
|
UPDATE x1 SET c=19 WHERE rowid=2;
|
|
}
|
|
|
|
do_execsql_test 3.3 $idxcheck 2
|
|
|
|
do_execsql_test 3.4 {
|
|
DELETE FROM y1 WHERE a=4;
|
|
}
|
|
do_execsql_test 3.5 $idxcheck {}
|
|
|
|
#-------------------------------------------------------------------------
|
|
reset_db
|
|
do_execsql_test 4.0 {
|
|
CREATE TABLE z1(a INTEGER PRIMARY KEY, b);
|
|
CREATE INDEX z1b ON z1(b+0.0);
|
|
INSERT INTO z1 VALUES(1, 1.0);
|
|
INSERT INTO z1 VALUES(2, 4.0);
|
|
INSERT INTO z1 VALUES(3, 4.0);
|
|
INSERT INTO z1 VALUES(4, 4.0);
|
|
INSERT INTO z1 VALUES(5, 4.0);
|
|
INSERT INTO z1 VALUES(6, 4.0);
|
|
INSERT INTO z1 VALUES(7, 4.0);
|
|
INSERT INTO z1 VALUES(8, 1.0);
|
|
}
|
|
|
|
set root [db one {SELECT rootpage FROM sqlite_schema WHERE name='z1b'}]
|
|
do_test 4.1 {
|
|
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 $root
|
|
db eval { CREATE TABLE x1(b, a, PRIMARY KEY(b, a)) WITHOUT ROWID; }
|
|
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 0
|
|
} {}
|
|
|
|
do_execsql_test 4.2 {
|
|
UPDATE x1 SET b=4.000000000000001 WHERE a=2; -- 1 ULP
|
|
UPDATE x1 SET b=4.000000000000002 WHERE a=3; -- 2 ULP
|
|
UPDATE x1 SET b=4.000000000000003 WHERE a=4; -- 3 ULP
|
|
UPDATE x1 SET b=3.9999999999999996 WHERE a=5; -- -1 ULP
|
|
UPDATE x1 SET b=3.9999999999999992 WHERE a=6; -- -2 ULP
|
|
UPDATE x1 SET b=3.9999999999999988 WHERE a=7; -- -3 ULP
|
|
}
|
|
|
|
do_execsql_test 4.3 {
|
|
PRAGMA integrity_check
|
|
} {
|
|
{index z1b stores an imprecise floating-point value for row 2}
|
|
{index z1b stores an imprecise floating-point value for row 3}
|
|
{row 4 missing from index z1b}
|
|
{index z1b stores an imprecise floating-point value for row 5}
|
|
{index z1b stores an imprecise floating-point value for row 6}
|
|
{row 7 missing from index z1b}
|
|
}
|
|
|
|
do_execsql_test 4.4 {
|
|
UPDATE z1 SET b=-4.0 WHERE b=4.0;
|
|
PRAGMA integrity_check;
|
|
} {ok}
|
|
|
|
do_execsql_test 4.5 {
|
|
UPDATE x1 SET b=-4.000000000000001 WHERE a=2; -- -1 ULP
|
|
UPDATE x1 SET b=-4.000000000000002 WHERE a=3; -- -2 ULP
|
|
UPDATE x1 SET b=-4.000000000000003 WHERE a=4; -- -3 ULP
|
|
UPDATE x1 SET b=-3.9999999999999996 WHERE a=5; -- 1 ULP
|
|
UPDATE x1 SET b=-3.9999999999999992 WHERE a=6; -- 2 ULP
|
|
UPDATE x1 SET b=-3.9999999999999988 WHERE a=7; -- 3 ULP
|
|
}
|
|
|
|
do_execsql_test 4.6 {
|
|
PRAGMA integrity_check
|
|
} {
|
|
{index z1b stores an imprecise floating-point value for row 2}
|
|
{index z1b stores an imprecise floating-point value for row 3}
|
|
{row 4 missing from index z1b}
|
|
{index z1b stores an imprecise floating-point value for row 5}
|
|
{index z1b stores an imprecise floating-point value for row 6}
|
|
{row 7 missing from index z1b}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
finish_test
|