should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,142 @@
# name: test/sql/index/art/constraints/test_art_compound_key_changes.test
# description: Tests various changes to compound indexes with out-of-order columns.
# group: [constraints]
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_comp (
a INT,
b VARCHAR UNIQUE,
gen AS (2 * a),
c INT,
d VARCHAR,
PRIMARY KEY (c, b));
statement ok
CREATE UNIQUE INDEX unique_idx ON tbl_comp((d || 'hello'), (a + 42));
statement ok
CREATE INDEX normal_idx ON tbl_comp(d, a, c);
statement ok
CREATE UNIQUE INDEX lookup_idx ON tbl_comp(c);
statement ok
INSERT INTO tbl_comp VALUES (1, 'hello', 1, 'hello');
statement ok
INSERT INTO tbl_comp VALUES (2, 'hello', 1, 'world')
ON CONFLICT (c, b) DO UPDATE SET a = excluded.a, d = excluded.d;
query IIIII
SELECT a, b, gen, c, d FROM tbl_comp WHERE c = 1;
----
2 hello 4 1 world
# Trigger unique_idx.
statement error
INSERT INTO tbl_comp VALUES (2, 'hola', 5, 'world');
----
<REGEX>:Constraint Error.*violates unique constraint.*
# Trigger lookup_idx.
statement error
INSERT INTO tbl_comp VALUES (3, 'hoi', 1, 'wereld');
----
<REGEX>:Constraint Error.*violates unique constraint.*
statement ok
INSERT INTO tbl_comp VALUES (3, 'hoi', 2, 'wereld');
query IIIII
SELECT a, b, gen, c, d FROM tbl_comp ORDER BY ALL;
----
2 hello 4 1 world
3 hoi 6 2 wereld
# Trigger the primary key.
statement error
INSERT INTO tbl_comp VALUES (42, 'hoi', 2, 'welt');
----
<REGEX>:Constraint Error.*violates unique constraint.*
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
statement ok old
INSERT INTO tbl_comp VALUES (42, 'hoii', 22, 'welt');
# con1 open.
statement ok con1
BEGIN;
statement ok con1
DELETE FROM tbl_comp;
statement ok con1
INSERT INTO tbl_comp VALUES (200, 'hello', 1, 'world'), (300, 'hoi', 2, 'wereld');
# Ensure that we can still see the old value.
query IIIII
SELECT a, b, gen, c, d FROM tbl_comp WHERE c = 2;
----
3 hoi 6 2 wereld
query IIIII
SELECT a, b, gen, c, d FROM tbl_comp WHERE c = 1;
----
2 hello 4 1 world
# Now commit the changes.
statement ok con1
COMMIT;
query IIIII
SELECT a, b, gen, c, d FROM tbl_comp ORDER BY ALL;
----
200 hello 400 1 world
300 hoi 600 2 wereld
query IIIII
SELECT a, b, gen, c, d FROM tbl_comp WHERE c = 2;
----
300 hoi 600 2 wereld
query IIIII
SELECT a, b, gen, c, d FROM tbl_comp WHERE c = 1;
----
200 hello 400 1 world
# Ensure that the old transaction can still see the old storage.
query IIIII old
SELECT a, b, gen, c, d FROM tbl_comp WHERE c = 2;
----
3 hoi 6 2 wereld
query IIIII old
SELECT a, b, gen, c, d FROM tbl_comp WHERE c = 1;
----
2 hello 4 1 world
statement ok old
COMMIT;
# Final results.
query IIIII
SELECT a, b, gen, c, d FROM tbl_comp ORDER BY ALL;
----
42 hoii 84 22 welt
200 hello 400 1 world
300 hoi 600 2 wereld

View File

@@ -0,0 +1,51 @@
# name: test/sql/index/art/constraints/test_art_concurrent_loop.test_slow
# description: Test repeated DELETE + INSERT in a concurrent loop.
# group: [constraints]
# We must never throw a constraint violation.
statement ok
CREATE TABLE tbl (i INT PRIMARY KEY);
statement ok
INSERT INTO tbl SELECT * FROM range(10000);
concurrentloop threadid 0 20
loop i 0 100
statement ok
BEGIN;
statement maybe
DELETE FROM tbl WHERE i = ${i} + ${threadid} * 10;
----
TransactionContext Error
statement maybe
INSERT INTO tbl VALUES (${i} + ${threadid} * 10);
----
TransactionContext Error
statement maybe
COMMIT;
----
TransactionContext Error
endloop
endloop
query II
SELECT COUNT(*), SUM(i) FROM tbl;
----
10000 49995000
loop i 0 10000
query I
SELECT i = ${i} FROM tbl WHERE i = ${i};
----
true
endloop

View File

@@ -0,0 +1,48 @@
# name: test/sql/index/art/constraints/test_art_eager_batch_insert.test
# description: Test eager constraint checking during batch inserts.
# group: [constraints]
statement ok
CREATE TABLE test1 (id INT PRIMARY KEY, payload VARCHAR);
statement ok
CREATE TABLE test2 (id INT PRIMARY KEY, payload VARCHAR);
statement ok
INSERT INTO test1 VALUES (1, 'row 1');
statement ok
INSERT INTO test2 VALUES (1, 'row 1 from test 2');
query II
SELECT id, payload FROM test1;
----
1 row 1
statement ok
BEGIN;
statement ok
DELETE FROM test1 WHERE id = 1;
query II
SELECT id, payload FROM test1;
----
statement ok
INSERT INTO test1 SELECT * FROM test2;
query II
SELECT id, payload FROM test1;
----
1 row 1 from test 2
statement ok
COMMIT
query II
SELECT id, payload FROM test1;
----
1 row 1 from test 2

View File

@@ -0,0 +1,266 @@
# name: test/sql/index/art/constraints/test_art_eager_constraint_checking.test
# description: Contains tests previously triggering the eager constraint checking limitation.
# group: [constraints]
statement ok
SET immediate_transaction_mode = true;
# Original issue: 7182
statement ok
CREATE TABLE t_7182 (it INTEGER PRIMARY KEY, jt INTEGER);
statement ok
CREATE TABLE u_7182 (iu INTEGER PRIMARY KEY, ju INTEGER REFERENCES t_7182 (it));
statement ok
INSERT INTO t_7182 VALUES (1, 1);
statement ok
INSERT INTO u_7182 VALUES (1, NULL);
statement ok
UPDATE u_7182 SET ju = 1 WHERE iu = 1;
query III
SELECT iu, ju, rowid FROM u_7182 WHERE iu = 1;
----
1 1 1
# Original issue: 5807
statement ok
CREATE TABLE tunion_5807 (id INTEGER PRIMARY KEY, u UNION (i int));
statement ok
INSERT INTO tunion_5807 SELECT 1, 41;
statement ok
UPDATE tunion_5807 SET u = 42 WHERE id = 1;
query III
SELECT id, u, rowid FROM tunion_5807 WHERE id = 1;
----
1 42 1
# Original issue: 5771
statement ok
CREATE TABLE IF NOT EXISTS workers_5771 (
id INTEGER PRIMARY KEY NOT NULL,
worker VARCHAR(150) UNIQUE NOT NULL,
phone VARCHAR(20) NOT NULL);
statement ok
INSERT INTO workers_5771 VALUES (1, 'wagner', '123');
statement ok
UPDATE workers_5771 SET phone = '345' WHERE id = 1;
statement ok
UPDATE workers_5771 SET worker = 'leo' WHERE id = 1;
query IIII
SELECT id, worker, phone, rowid FROM workers_5771 WHERE id = 1;
----
1 leo 345 1
# Original issue: 4886
statement ok
CREATE TABLE test_4886 (i INTEGER PRIMARY KEY);
statement ok
INSERT INTO test_4886 VALUES (1);
statement ok
BEGIN;
statement ok
UPDATE test_4886 SET i = 4 WHERE i = 1;
statement ok
INSERT INTO test_4886 VALUES (1);
statement ok
COMMIT
query II
SELECT i, rowid FROM test_4886 ORDER BY ALL;
----
1 2
4 1
query II
SELECT i, rowid FROM test_4886 WHERE i = 1;
----
1 2
query II
SELECT i, rowid FROM test_4886 WHERE i = 4;
----
4 1
# Original issue: 1631
statement ok
CREATE TABLE tbl_1631 (
id INTEGER PRIMARY KEY,
c1 text NOT NULL UNIQUE,
c2 text NOT NULL);
statement ok
INSERT INTO tbl_1631 VALUES (1, 'abc', 'def'), (2, 'asdf', 'jkl');
statement ok
UPDATE tbl_1631 SET c1 = 'ghi', c2 = 'mno' WHERE id = 2;
query IIII
SELECT id, c1, c2, rowid FROM tbl_1631 ORDER BY ALL;
----
1 abc def 0
2 ghi mno 2
# Original issue: 4214
statement ok
CREATE TABLE c_4214 (id INTEGER NOT NULL PRIMARY KEY);
statement ok
CREATE TABLE a_4214 (
id INTEGER NOT NULL PRIMARY KEY,
c_id INTEGER NOT NULL,
FOREIGN KEY(c_id) REFERENCES c_4214 (id)
);
statement ok
INSERT INTO c_4214 (id) VALUES (1), (2);
statement ok
INSERT INTO a_4214 (id, c_id) VALUES (1, 1);
statement ok
UPDATE a_4214 SET c_id = 2 WHERE id = 1;
query III
SELECT id, c_id, rowid FROM a_4214 WHERE id = 1;
----
1 2 1
# Original issue: 8764 (altered)
statement ok
CREATE TABLE tag_8764 (
key VARCHAR(65535) NOT NULL,
name VARCHAR(65535) NULL,
value VARCHAR(65535) NOT NULL,
PRIMARY KEY (key, name)
);
statement ok
CREATE UNIQUE INDEX idx_name_8764 ON tag_8764(name);
statement ok
CREATE UNIQUE INDEX idx_value_8764 ON tag_8764(value);
statement ok
INSERT INTO tag_8764 (key, name, value) VALUES ('key1', 'name1', 'value1');
statement ok
UPDATE tag_8764 SET value = 'new_value' WHERE key = 'key1' AND name = 'name1';
query IIII
SELECT key, name, value, rowid FROM tag_8764;
----
key1 name1 new_value 1
# Original issue: 11288
statement ok
CREATE TABLE t_11288 (i INT PRIMARY KEY, j MAP(VARCHAR, VARCHAR));
statement ok
INSERT INTO t_11288 VALUES (1, MAP(['a'], ['b']));
statement ok
UPDATE t_11288 SET j = MAP(['c'], ['d']) WHERE i = 1;
query II
SELECT i, j FROM t_11288 WHERE i = 1;
----
1 {c=d}
# Original issue: 4807
statement ok
CREATE TABLE t_4807 (id INT PRIMARY KEY, u UNION (i INT));
statement ok
INSERT INTO t_4807 SELECT 1, 41;
statement ok
UPDATE t_4807 SET u = 42 WHERE id = 1;
query III
SELECT id, u, rowid FROM t_4807;
----
1 42 1
# Original issue: 14133
statement ok
CREATE TABLE t_14133 (i INT PRIMARY KEY, s VARCHAR);
statement ok
INSERT INTO t_14133 SELECT i, i::string FROM generate_series(1, 100) s(i);
statement ok
BEGIN;
statement ok
DELETE FROM t_14133 WHERE i IN (SELECT i FROM generate_series(1, 20) s(i));
statement ok
INSERT OR REPLACE INTO t_14133 SELECT i, (i * 2)::string FROM generate_series(1, 20) s(i);
statement ok
COMMIT;
query III
SELECT COUNT(*), MIN(i), MAX(i) FROM t_14133;
----
100 1 100
# Original issue: 6500
load __TEST_DIR__/eager_constraint_issue.db
statement ok
CREATE TABLE tbl_6500 (i INTEGER, j INTEGER);
statement ok
INSERT INTO tbl_6500 VALUES (1, 100), (2, 200);
statement ok
CREATE UNIQUE INDEX idx_6500 ON tbl_6500 (i);
statement ok
CHECKPOINT;
statement ok
INSERT OR IGNORE INTO tbl_6500 VALUES (1, 101), (2, 201);
query II
SELECT i, j FROM tbl_6500 ORDER BY ALL;
----
1 100
2 200
statement ok
INSERT INTO tbl_6500 VALUES (1,101), (2,201) ON CONFLICT DO NOTHING;
query II
SELECT i, j FROM tbl_6500 ORDER BY ALL;
----
1 100
2 200

View File

@@ -0,0 +1,50 @@
# name: test/sql/index/art/constraints/test_art_eager_update.test_slow
# description: Test ART BIGINT key type
# group: [constraints]
statement ok
PRAGMA enable_verification
statement ok
CREATE OR REPLACE TABLE t (
s UUID,
payload STRUCT(k VARCHAR)[],
p STRUCT(e VARCHAR, s DOUBLE),
payload2 STRUCT(x INT)[],
other VARCHAR
);
statement ok
CREATE OR REPLACE TABLE t2 (
s UUID,
payload STRUCT(k VARCHAR)[],
p STRUCT(e VARCHAR, s DOUBLE),
payload2 STRUCT(x INT)[]
);
statement ok
INSERT INTO t(s, other) (
SELECT s, SUBSTRING(s::VARCHAR, 1, 8) AS other
FROM (SELECT uuid() AS s FROM range(300000))
);
statement ok
INSERT INTO t2 (
SELECT
s,
[struct_pack(k := 'aaaa'), struct_pack(k := 'rrrr')],
struct_pack(e := 'ddd', s := -9.0),
[struct_pack(x := 99), struct_pack(x := 100), struct_pack(x := 101)]
FROM t WHERE rowid % 2 = 0
);
statement ok
ALTER TABLE t ADD PRIMARY KEY (s);
statement ok
ALTER TABLE t2 ADD PRIMARY KEY (s);
statement ok
UPDATE t
SET payload = t2.payload, p = t2.p, payload2 = t2.payload2
FROM t2 WHERE t.s = t2.s;

View File

@@ -0,0 +1,36 @@
# name: test/sql/index/art/constraints/test_art_eager_with_wal.test
# description: Test eager constraint checking with WAL replay.
# group: [constraints]
load __TEST_DIR__/pk_duplicate_key_wal.db
statement ok
SET checkpoint_threshold = '10.0 GB';
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
CREATE TABLE tbl (id INT PRIMARY KEY);
statement ok
INSERT INTO tbl VALUES (1);
statement ok
BEGIN;
statement ok
DELETE FROM tbl WHERE id = 1;
statement ok
INSERT INTO tbl VALUES (1);
statement ok
COMMIT;
restart
statement error
INSERT INTO tbl VALUES (1);
----
<REGEX>:Constraint Error.*violates primary key constraint.*

View File

@@ -0,0 +1,56 @@
# name: test/sql/index/art/constraints/test_art_large_abort.test
# description: Test abort of large insertion of negative values into index and verify that all elements are correctly deleted
# group: [constraints]
statement ok
CREATE TABLE a(id INTEGER PRIMARY KEY, c INT);
statement ok
INSERT INTO a VALUES (1, 4)
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO a SELECT i id, NULL c FROM range(-2, -250000, -1) tbl(i)
statement error
INSERT INTO a VALUES (1, 5)
----
statement ok
ROLLBACK
query I
SELECT c FROM a WHERE id=1
----
4
query II
SELECT * FROM a
----
1 4
# now with non-null values
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO a SELECT i id, -i c FROM range(-2, -250000, -1) tbl(i)
statement error
INSERT INTO a VALUES (1, 5)
----
statement ok
ROLLBACK
query I
SELECT c FROM a WHERE id=1
----
4
query II
SELECT * FROM a
----
1 4

View File

@@ -0,0 +1,36 @@
# name: test/sql/index/art/constraints/test_art_simple_update.test
# description: Test a simple update on a PK with a LIST column.
# group: [constraints]
statement ok
CREATE TABLE tbl (i BIGINT PRIMARY KEY, l1 BIGINT[]);
statement ok
INSERT INTO tbl VALUES(1, [1, 2, 3]), (2, [42]);
query III
SELECT i, l1, rowid FROM tbl ORDER BY ALL;
----
1 [1, 2, 3] 0
2 [42] 1
statement ok
UPDATE tbl SET l1 = [1, 2, 4] WHERE i = 1;
query III
SELECT i, l1, rowid FROM tbl ORDER BY ALL;
----
1 [1, 2, 4] 2
2 [42] 1
statement ok
INSERT OR REPLACE INTO tbl VALUES (2, [43]);
statement ok
INSERT OR REPLACE INTO tbl VALUES (2, [44]);
query III
SELECT i, l1, rowid FROM tbl ORDER BY ALL;
----
1 [1, 2, 4] 2
2 [44] 4

View File

@@ -0,0 +1,59 @@
# name: test/sql/index/art/constraints/test_art_tx_delete_with_global_nested.test
# description: Test DELETE + INSERT while the global ART has nested leaves.
# group: [constraints]
load __TEST_DIR__/test_art_tx_delete_with_global_nested.db
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl VALUES (1, ['first payload']);
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
# Now update the ART via DELETE + INSERT.
statement ok con1
BEGIN;
statement ok con1
DELETE FROM tbl WHERE id = 1;
statement ok con1
INSERT INTO tbl VALUES (1, ['con1 payload']);
statement ok con1
COMMIT;
# The ART leaf contains both the new and the old row ID.
statement ok con2
BEGIN
statement ok con2
DELETE FROM tbl WHERE id = 1;
statement ok con2
INSERT INTO tbl VALUES (1, ['con2 payload']);
# Unique indexes can have a maximum of two row IDs in their leaves.
statement error con2
COMMIT;
----
<REGEX>:TransactionContext Error.*write-write conflict on key.*
statement ok old
COMMIT;
query III
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 [con1 payload] 1

View File

@@ -0,0 +1,75 @@
# name: test/sql/index/art/constraints/test_art_tx_deletes_list.test
# description: Test DELETE + INSERT with different connections and LIST payload.
# group: [constraints]
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_list (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_list VALUES (1, ['first payload']);
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
statement ok old
INSERT INTO tbl_list VALUES (5, ['old payload']);
# con1 open.
statement ok con1
BEGIN;
statement ok con1
DELETE FROM tbl_list;
statement ok con1
INSERT INTO tbl_list VALUES (1, ['con1 payload']);
# Ensure that we can still see the old value.
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [first payload] 0
# Try to delete again.
statement ok
BEGIN;
statement error
DELETE FROM tbl_list;
----
<REGEX>:TransactionContext Error.*Conflict on tuple deletion.*
statement ok
ROLLBACK;
statement ok con1
COMMIT;
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [con1 payload] 1
# Ensure that the old transaction can still see the old storage.
query III old
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [first payload] 0
statement ok old
COMMIT;
query III
SELECT id, payload, rowid FROM tbl_list ORDER BY ALL;
----
1 [con1 payload] 1
5 [old payload] 2

View File

@@ -0,0 +1,39 @@
# name: test/sql/index/art/constraints/test_art_tx_deletes_rollback.test
# description: Test DELETE + INSERT, then ROLLBACK due to a constraint violation.
# group: [constraints]
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_rollback (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_rollback VALUES (1, ['first payload']);
statement ok con1
BEGIN;
statement ok con1
DELETE FROM tbl_rollback;
statement ok con1
INSERT INTO tbl_rollback VALUES (1, ['con1 payload']);
statement error con1
INSERT INTO tbl_rollback VALUES (1, ['con1 payload']);
----
<REGEX>:Constraint Error.*PRIMARY KEY or UNIQUE constraint violation.*
statement error con1
SELECT 42;
----
<REGEX>:TransactionContext Error.*Current transaction is aborted.*
statement ok con1
ROLLBACK;
query III
SELECT id, payload, rowid FROM tbl_rollback ORDER BY ALL;
----
1 [first payload] 0

View File

@@ -0,0 +1,76 @@
# name: test/sql/index/art/constraints/test_art_tx_deletes_varchar.test
# description: Test DELETE + INSERT with different connections and VARCHAR payload.
# group: [constraints]
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl (id INT PRIMARY KEY, payload VARCHAR);
statement ok
INSERT INTO tbl VALUES (1, 'first payload');
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
statement ok old
INSERT INTO tbl VALUES (5, 'old payload');
# con1 open.
statement ok con1
BEGIN;
statement ok con1
DELETE FROM tbl;
statement ok con1
INSERT INTO tbl VALUES (1, 'con1 payload');
# Ensure that we can still see the old value.
query III
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 first payload 0
# Try to delete again.
statement ok
BEGIN;
statement error
DELETE FROM tbl;
----
<REGEX>:TransactionContext Error.*Conflict on tuple deletion.*
statement ok
ROLLBACK;
statement ok con1
COMMIT;
query III
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 con1 payload 1
# Ensure that the old transaction can still see the old storage.
query III old
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 first payload 0
statement ok old
COMMIT;
query III
SELECT id, payload, rowid FROM tbl ORDER BY ALL;
----
1 con1 payload 1
5 old payload 2

View File

@@ -0,0 +1,35 @@
# name: test/sql/index/art/constraints/test_art_tx_returning.test
# description: Test updates on the primary key containing RETURNING.
# group: [constraints]
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_list (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_list SELECT range, [range || ' payload'] FROM range(5);
query II
UPDATE tbl_list SET id = id + 5 RETURNING id, payload;
----
5 [0 payload]
6 [1 payload]
7 [2 payload]
8 [3 payload]
9 [4 payload]
statement ok
INSERT INTO tbl_list SELECT range + 10, [(range + 10) || ' payload'] FROM range(3000);
# For each incoming chunk, we add the row IDs to the delete index.
# For standard_vector_size = 2048, we delete the first chunk, and then try to insert the incremented values.
# This is expected to throw a constraint violation.
# The value going into the next chunk is not yet in the delete index, as the chunk that would add that value hasn't been processed, yet.
# This scenario is a known limitation (also in postgres).
statement error
UPDATE tbl_list SET id = id + 1 RETURNING id, payload;
----
<REGEX>:Constraint Error.*violates primary key constraint.*

View File

@@ -0,0 +1,29 @@
# name: test/sql/index/art/constraints/test_art_tx_same_row_id.test
# description: Test deletes that touch the same row ID repeatedly.
# group: [constraints]
# FIXME: We need to fix the internal issue #3702
mode skip
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_list (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_list SELECT range, [range || ' payload'] FROM range(10);
query II
DELETE FROM tbl_list USING range(100) t(i) RETURNING id, payload;
----
0 [0 payload]
1 [1 payload]
2 [2 payload]
3 [3 payload]
4 [4 payload]
5 [5 payload]
6 [6 payload]
7 [7 payload]
8 [8 payload]
9 [9 payload]

View File

@@ -0,0 +1,56 @@
# name: test/sql/index/art/constraints/test_art_tx_update_with_global_nested.test
# description: Test UPDATE while the global ART has nested leaves.
# group: [constraints]
load __TEST_DIR__/test_art_tx_update_with_global_nested.db
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl VALUES (1, ['first payload']);
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
# Now update the ART via UPDATE.
statement ok con1
BEGIN;
statement ok con1
UPDATE tbl SET payload = ['con1 payload'] WHERE id = 1;
statement ok con1
COMMIT;
# The ART leaf contains both the new and the old row ID.
statement ok con2
BEGIN
statement ok con2
UPDATE tbl SET payload = ['con2 payload'] WHERE id = 1;
# Unique indexes can have a maximum of two row IDs in their leaves.
statement error con2
COMMIT;
----
<REGEX>:TransactionContext Error.*write-write conflict on key.*
statement ok old
COMMIT;
query III
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 [con1 payload] 1

View File

@@ -0,0 +1,103 @@
# name: test/sql/index/art/constraints/test_art_tx_updates_list.test
# description: Test UPDATE with different connections and LIST payload.
# group: [constraints]
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_list (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_list VALUES (1, ['first payload']), (2, ['second payload']);
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
statement ok old
INSERT INTO tbl_list VALUES (5, ['old payload']);
# con1 open.
statement ok con1
BEGIN;
statement ok con1
UPDATE tbl_list SET payload = ['con1 payload'] WHERE id = 1;
statement ok con1
UPDATE tbl_list SET id = 3 WHERE id = 2;
statement ok con1
INSERT INTO tbl_list VALUES (2, ['new payload']);
# Ensure that we can still see the old value.
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [first payload] 0
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 2;
----
2 [second payload] 1
# Try to update again.
statement ok
BEGIN;
statement error
UPDATE tbl_list SET payload = ['second payload'] WHERE id = 1;
----
<REGEX>:TransactionContext Error.*Conflict on tuple deletion.*
statement ok
ROLLBACK;
statement ok con1
COMMIT;
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [con1 payload] 2
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 2;
----
2 [new payload] 4
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 3;
----
3 [second payload] 3
# Ensure that the old transaction can still see the old storage.
query III old
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [first payload] 0
query III old
SELECT id, payload, rowid FROM tbl_list WHERE id = 2;
----
2 [second payload] 1
statement ok old
COMMIT;
query III
SELECT id, payload, rowid FROM tbl_list ORDER BY ALL;
----
1 [con1 payload] 2
2 [new payload] 4
3 [second payload] 3
5 [old payload] 5

View File

@@ -0,0 +1,116 @@
# name: test/sql/index/art/constraints/test_art_tx_updates_pk_col.test
# description: Test UPDATE on the PK column with different connections and VARCHAR payload.
# group: [constraints]
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl (id INT PRIMARY KEY, payload VARCHAR);
statement ok
INSERT INTO tbl VALUES (1, 'first payload');
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
statement ok old
INSERT INTO tbl VALUES (5, 'old payload');
# con1 open.
statement ok con1
BEGIN;
statement ok con1
UPDATE tbl SET id = 3 WHERE id = 1;
statement ok con1
INSERT INTO tbl VALUES (1, 'new payload');
# Ensure that we can still see the old value.
query III
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 first payload 0
# Locally update the payload.
statement ok
BEGIN;
statement ok
UPDATE tbl SET payload = 'second payload' WHERE id = 1;
# Transaction-local state.
query II
SELECT id, payload FROM tbl WHERE id = 1;
----
1 second payload
# Transaction-local state.
query II con1
SELECT id, payload FROM tbl WHERE id = 3;
----
3 first payload
query II con1
SELECT id, payload FROM tbl WHERE id = 1;
----
1 new payload
statement ok con1
COMMIT;
# We only see the local changes.
query III
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 second payload 0
query III
SELECT id, payload, rowid FROM tbl WHERE id = 3;
----
# This runs into a write-write conflict on commit and rolls back.
statement ok
COMMIT;
# The result are the committed changes of con1.
query III
SELECT id, payload, rowid FROM tbl WHERE id = 3;
----
3 first payload 1
query III
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 new payload 2
# Ensure that the old transaction can still see the old storage.
query III old
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 first payload 0
statement ok old
COMMIT;
query III
SELECT id, payload, rowid FROM tbl ORDER BY ALL;
----
1 new payload 2
3 first payload 1
5 old payload 3

View File

@@ -0,0 +1,39 @@
# name: test/sql/index/art/constraints/test_art_tx_updates_rollback.test
# description: Test UPDATE, then ROLLBACK due to a constraint violation.
# group: [constraints]
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_rollback (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_rollback VALUES (1, ['first payload']);
statement ok con1
BEGIN;
statement ok con1
UPDATE tbl_rollback SET payload = ['con1 payload'] WHERE id = 1;
statement error con1
INSERT INTO tbl_rollback VALUES (1, ['con1 payload']);
----
<REGEX>:Constraint Error.*PRIMARY KEY or UNIQUE constraint violation.*
statement error con1
SELECT 42;
----
<REGEX>:TransactionContext Error.*Current transaction is aborted.*
statement ok con1
ROLLBACK;
query III
SELECT id, payload, rowid FROM tbl_rollback ORDER BY ALL;
----
1 [first payload] 0

View File

@@ -0,0 +1,54 @@
# name: test/sql/index/art/constraints/test_art_tx_upsert_with_global_nested.test
# description: Test UPSERT while the global ART has nested leaves.
# group: [constraints]
load __TEST_DIR__/test_art_tx_upsert_with_global_nested.db
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl VALUES (1, ['first payload']);
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
# Now update the ART via UPSERT.
statement ok con1
BEGIN;
statement ok con1
INSERT OR REPLACE INTO tbl VALUES (1, ['con1 payload']);
statement ok con1
COMMIT;
# The ART leaf contains both the new and the old row ID.
statement ok con2
BEGIN
statement ok con2
INSERT OR REPLACE INTO tbl VALUES (1, ['con2 payload']);
statement error con2
COMMIT;
----
<REGEX>:TransactionContext Error.*write-write conflict on key.*
statement ok old
COMMIT;
query III
SELECT id, payload, rowid FROM tbl WHERE id = 1;
----
1 [con1 payload] 1

View File

@@ -0,0 +1,75 @@
# name: test/sql/index/art/constraints/test_art_tx_upserts_list.test
# description: Test UPSERT with different connections and LIST payload.
# group: [constraints]
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_list (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_list VALUES (1, ['first payload']);
# Keep one connection open to ensure we still have the old value in the ART.
statement ok old
BEGIN;
statement ok old
INSERT INTO tbl_list VALUES (5, ['old payload']);
# con1 open.
statement ok con1
BEGIN;
statement ok con1
INSERT OR REPLACE INTO tbl_list VALUES (1, ['con1 payload']);
# Ensure that we can still see the old value.
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [first payload] 0
# Try to upsert again.
statement ok
BEGIN;
statement error
INSERT OR REPLACE INTO tbl_list VALUES (1, ['second payload']);
----
<REGEX>:TransactionContext Error.*Conflict on tuple deletion.*
statement ok
ROLLBACK;
statement ok con1
COMMIT;
query III
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [con1 payload] 1
# Ensure that the old transaction can still see the old storage.
query III old
SELECT id, payload, rowid FROM tbl_list WHERE id = 1;
----
1 [first payload] 0
statement ok old
COMMIT;
query III
SELECT id, payload, rowid FROM tbl_list ORDER BY ALL;
----
1 [con1 payload] 1
5 [old payload] 2

View File

@@ -0,0 +1,51 @@
# name: test/sql/index/art/constraints/test_art_tx_upserts_local.test
# description: Test multiple UPSERTs in a connection with LIST payload.
# group: [constraints]
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_local (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_local VALUES (1, ['first payload']);
statement ok con1
BEGIN;
statement ok con1
INSERT OR REPLACE INTO tbl_local VALUES (1, ['con1 payload']);
statement ok con1
INSERT OR REPLACE INTO tbl_local VALUES (1, ['local payload']);
query III
SELECT id, payload, rowid FROM tbl_local WHERE id = 1;
----
1 [first payload] 0
statement ok con1
COMMIT;
query III
SELECT id, payload, rowid FROM tbl_local WHERE id = 1;
----
1 [local payload] 1
statement ok con1
BEGIN;
statement ok con1
INSERT OR REPLACE INTO tbl_local VALUES (1, ['val2 payload']), (1, ['val2 payload']);
statement ok con1
COMMIT;
query III
SELECT id, payload, rowid FROM tbl_local WHERE id = 1;
----
1 [val2 payload] 2

View File

@@ -0,0 +1,42 @@
# name: test/sql/index/art/constraints/test_art_tx_upserts_rollback.test
# description: Test UPSERT, then ROLLBACK due to a constraint violation.
# group: [constraints]
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode = true;
statement ok
CREATE TABLE tbl_rollback (id INT PRIMARY KEY, payload VARCHAR[]);
statement ok
INSERT INTO tbl_rollback VALUES (1, ['first payload']);
statement ok con1
BEGIN;
statement ok con1
INSERT OR REPLACE INTO tbl_rollback VALUES (1, ['con1 payload']);
statement ok con1
INSERT INTO tbl_rollback VALUES (2, ['second payload']);
statement error con1
INSERT INTO tbl_rollback VALUES (2, ['second payload']);
----
<REGEX>:Constraint Error.*PRIMARY KEY or UNIQUE constraint violation.*
statement error con1
SELECT 42;
----
<REGEX>:TransactionContext Error.*Current transaction is aborted.*
statement ok con1
ROLLBACK;
query III
SELECT id, payload, rowid FROM tbl_rollback ORDER BY ALL;
----
1 [first payload] 0

View File

@@ -0,0 +1,28 @@
# name: test/sql/index/art/constraints/test_art_upsert_duplicate.test
# description: Test an UPSERT with a duplicate in the VALUES list.
# group: [constraints]
statement ok
PRAGMA enable_verification;
statement ok
CREATE TABLE hero (
name VARCHAR NOT NULL,
secret_name VARCHAR NOT NULL,
age INTEGER,
PRIMARY KEY (name));
statement ok
CREATE INDEX ix_hero_age ON hero (age);
statement ok
INSERT INTO hero (name, secret_name, age)
VALUES
('Captain North America', 'Esteban Rogelios', 93),
('Rusty-Man', 'Tommy Sharp', 48),
('Tarantula', 'Natalia Roman-on', 32),
('Spider-Boy', 'Pedro Parqueador', 17),
('Captain North America', 'Esteban Rogelios', 93)
ON CONFLICT (name) DO UPDATE
SET secret_name = EXCLUDED.secret_name,
age = EXCLUDED.age;

View File

@@ -0,0 +1,46 @@
# name: test/sql/index/art/constraints/test_art_upsert_other_index.test
# description: Test an UPSERT SET expression targeting an indexed column.
# group: [constraints]
# Original issue: 2382
statement ok
PRAGMA enable_verification;
statement ok
CREATE TABLE kvp (
"key" VARCHAR PRIMARY KEY,
"value" VARCHAR,
expiration BIGINT,
"cache" BOOLEAN);
statement ok
CREATE INDEX kve_idx ON kvp (expiration);
statement ok
INSERT OR REPLACE INTO kvp VALUES ('/key', 'value', 0, false);
query IIII
SELECT key, value, expiration, cache FROM kvp;
----
/key value 0 false
statement ok
INSERT OR REPLACE INTO kvp VALUES ('/key', 'value', 10000000, false);
query IIII
SELECT key, value, expiration, cache FROM kvp;
----
/key value 0 false
statement ok
INSERT INTO kvp VALUES ('/key', 'value', 10000000, false)
ON CONFLICT DO UPDATE SET
value = excluded.value,
expiration = excluded.expiration,
cache = excluded.cache;
query IIII
SELECT key, value, expiration, cache FROM kvp;
----
/key value 10000000 false

View File

@@ -0,0 +1,63 @@
# name: test/sql/index/art/create_drop/test_art_create_if_exists.test
# description: Test ART creation with the same index already existing
# group: [create_drop]
statement ok
PRAGMA enable_verification;
statement ok
PRAGMA immediate_transaction_mode = True;
statement ok
CREATE TABLE tbl AS SELECT range AS i FROM range(100);
# Trigger write-write conflict.
statement ok con1
BEGIN;
statement ok con1
CREATE INDEX IF NOT EXISTS my_idx ON tbl(i);
statement ok con2
BEGIN;
statement error con2
CREATE INDEX IF NOT EXISTS my_idx ON tbl(i);
----
<REGEX>:TransactionContext Error.*write-write.*
statement ok con1
COMMIT;
statement ok con2
COMMIT;
query I
SELECT COUNT(*) FROM duckdb_indexes;
----
1
statement ok
DROP INDEX my_idx;
# Trigger early-out.
statement ok
CREATE INDEX IF NOT EXISTS my_idx ON tbl(i);
statement ok
CREATE INDEX IF NOT EXISTS my_idx ON tbl(i);
statement error
CREATE INDEX my_idx ON tbl(i);
----
<REGEX>:Catalog Error.*already exists.*
query I
SELECT COUNT(*) FROM duckdb_indexes;
----
1
statement ok
DROP INDEX my_idx;

View File

@@ -0,0 +1,54 @@
# name: test/sql/index/art/create_drop/test_art_create_index_delete.test
# description: Test ART creation with deletions and multiple connections
# group: [create_drop]
statement ok
PRAGMA enable_verification
statement ok
SET immediate_transaction_mode=true
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
INSERT INTO integers SELECT * FROM range(10)
statement ok con1
BEGIN
statement ok
DELETE FROM integers WHERE i=2 OR i=7
query I con1
SELECT * FROM integers WHERE i=1;
----
1
query I con1
SELECT * FROM integers WHERE i=2;
----
2
statement ok
CREATE INDEX i_index ON integers(i)
query I
SELECT * FROM integers WHERE i=1;
----
1
query I
SELECT * FROM integers WHERE i=2;
----
# connection 1 still sees the old state
query I con1
SELECT * FROM integers WHERE i=1;
----
1
query I con1
SELECT * FROM integers WHERE i=2;
----
2

View File

@@ -0,0 +1,31 @@
# name: test/sql/index/art/create_drop/test_art_create_index_duplicate_deletes.test
# description: Test ART index creation with deletes
# group: [create_drop]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
INSERT INTO integers SELECT * FROM range(10)
statement ok
DELETE FROM integers
statement ok
INSERT INTO integers SELECT * FROM range(10)
statement ok
CREATE INDEX i_index ON integers(i)
query I
SELECT * FROM integers WHERE i=1;
----
1
query I
SELECT * FROM integers WHERE i=2;
----
2

View File

@@ -0,0 +1,62 @@
# name: test/sql/index/art/create_drop/test_art_create_many_duplicates.test
# description: Test ART creation with many duplicates in leaves
# group: [create_drop]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO integers SELECT * FROM repeat(1, 1500) t1(i)
statement ok
INSERT INTO integers SELECT * FROM repeat(2, 1500) t1(i)
statement ok
INSERT INTO integers SELECT * FROM repeat(3, 1500) t1(i)
statement ok
INSERT INTO integers SELECT * FROM repeat(4, 1500) t1(i)
statement ok
COMMIT
statement ok
CREATE INDEX i_index ON integers(i)
query I
SELECT count(i) FROM integers WHERE i > 1 AND i < 3
----
1500
query I
SELECT count(i) FROM integers WHERE i >= 1 AND i < 3
----
3000
query I
SELECT count(i) FROM integers WHERE i > 1
----
4500
query I
SELECT count(i) FROM integers WHERE i < 4
----
4500
query I
SELECT count(i) FROM integers WHERE i < 5
----
6000
statement ok
DROP INDEX i_index
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,61 @@
# name: test/sql/index/art/create_drop/test_art_create_many_duplicates_deletes.test
# description: Test ART creation with many duplicates in leaves and deletions
# group: [create_drop]
statement ok
PRAGMA enable_verification
statement ok
BEGIN TRANSACTION
statement ok
CREATE TABLE integers(i integer)
statement ok
INSERT INTO integers SELECT * FROM repeat(1, 1500) t1(i)
statement ok
INSERT INTO integers SELECT * FROM repeat(2, 1500) t1(i)
statement ok
INSERT INTO integers SELECT * FROM repeat(3, 1500) t1(i)
statement ok
INSERT INTO integers SELECT * FROM repeat(4, 1500) t1(i)
statement ok
INSERT INTO integers SELECT * FROM repeat(5, 1500) t1(i)
statement ok
COMMIT
statement ok
DELETE FROM integers WHERE i = 5
statement ok
CREATE INDEX i_index ON integers(i)
query I
SELECT count(i) FROM integers WHERE i > 1 AND i < 3
----
1500
query I
SELECT count(i) FROM integers WHERE i >= 1 AND i < 3
----
3000
query I
SELECT count(i) FROM integers WHERE i > 1
----
4500
query I
SELECT count(i) FROM integers WHERE i < 4
----
4500
query I
SELECT count(i) FROM integers WHERE i < 5
----
6000

View File

@@ -0,0 +1,42 @@
# name: test/sql/index/art/create_drop/test_art_create_unique.test
# description: Test unique ART creation
# group: [create_drop]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE t0(c0 INTEGER);
statement ok
CREATE UNIQUE INDEX i0 ON t0(c0);
statement ok
INSERT INTO t0(c0) VALUES (1);
statement error
INSERT INTO t0(c0) VALUES (1);
----
<REGEX>:.*Constraint Error.*Duplicate key.*
query I
SELECT * FROM t0 WHERE t0.c0 = 1;
----
1
statement ok
CREATE TABLE merge_violation (id INT);
statement ok
INSERT INTO merge_violation SELECT range FROM range(2048);
statement ok
INSERT INTO merge_violation SELECT range + 10000 FROM range(2048);
statement ok
INSERT INTO merge_violation VALUES (2047);
statement error
CREATE UNIQUE INDEX idx ON merge_violation(id);
----
<REGEX>:.*Constraint Error.*contains duplicates on indexed column.*

View File

@@ -0,0 +1,71 @@
# name: test/sql/index/art/create_drop/test_art_drop_index.test
# description: Test the DROP INDEX statement
# group: [create_drop]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE A (A1 INTEGER,A2 VARCHAR, A3 INTEGER)
statement ok
INSERT INTO A VALUES (1, 1, 1)
statement ok
INSERT INTO A VALUES (2, 2, 2)
statement ok
CREATE TABLE B (B1 INTEGER,B2 INTEGER, B3 INTEGER)
statement ok
INSERT INTO B VALUES (1, 1, 1)
statement ok
INSERT INTO B VALUES (2, 2, 2)
statement ok
CREATE TABLE C (C1 VARCHAR, C2 INTEGER, C3 INTEGER)
statement ok
INSERT INTO C VALUES ('t1', 1, 1)
statement ok
INSERT INTO C VALUES ('t2', 2, 2)
query T
SELECT A2 FROM A WHERE A1=1
----
1
statement ok
CREATE INDEX A_index ON A (A1)
query T
SELECT A2 FROM A WHERE A1=1
----
1
statement ok
CREATE INDEX B_index ON B (B1)
query T
SELECT A2 FROM A WHERE A1=1
----
1
statement ok
CREATE INDEX C_index ON C (C2)
query T
SELECT A2 FROM A WHERE A1=1
----
1
statement ok
DROP INDEX IF EXISTS A_index
query T
SELECT A2 FROM A WHERE A1=1
----
1

View File

@@ -0,0 +1,54 @@
# name: test/sql/index/art/create_drop/test_art_invalid_create_index.test
# description: Test triggering different exceptions
# group: [create_drop]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i integer, j integer, k BOOLEAN)
statement error
CREATE INDEX ON integers(i)
----
<REGEX>:.*Not implemented Error.*provide an index name.*
statement error
CREATE INDEX i_index ON integers(i COLLATE "NOCASE")
----
<REGEX>:.*Not implemented Error.*Index with collation not supported yet.*
statement error
CREATE INDEX i_index ON integers(i COLLATE "de_DE")
----
<REGEX>:.*Not implemented Error.*Index with collation not supported yet.*
statement error
CREATE INDEX i_index ON integers using blabla(i)
----
<REGEX>:.*Binder Error.*Unknown index type.*
statement error
CREATE INDEX i_index ON integers(f)
----
<REGEX>:.*Binder Error.*does not have a column.*
# index on list columns
statement ok
create table lists(id int, l int[]);
statement error
create index i_index on lists(l);
----
<REGEX>:.*Invalid type Error.*Invalid type for index key.*
statement error
create index i_index on lists(id, l);
----
<REGEX>:.*Invalid type Error.*Invalid type for index key.*
# index on constant columns
statement error
create index i_index on integers(('hello'));
----
<REGEX>:.*Binder Error.*does not refer to any columns.*

View File

@@ -0,0 +1,49 @@
# name: test/sql/index/art/create_drop/test_art_long_keys.test_slow
# description: Test ART creation very long BLOBs.
# group: [create_drop]
# Try creating an index with identical long keys.
statement ok
CREATE TABLE long_strings (id BLOB);
statement ok
INSERT INTO long_strings SELECT repeat('k', 1000000);
statement ok
INSERT INTO long_strings SELECT range::VARCHAR::BLOB FROM range(100000);
statement ok
INSERT INTO long_strings SELECT repeat('k', 1000000);
statement ok
INSERT INTO long_strings SELECT range::VARCHAR::BLOB || 'other' FROM range(100000);
statement ok
INSERT INTO long_strings SELECT repeat('k', 1000000);
statement error
CREATE INDEX idx ON long_strings(id);
----
<REGEX>:Invalid Input Error.*exceeds the maximum size.*
# Now we try medium-sized keys.
statement ok
CREATE TABLE medium_strings (id BLOB);
statement ok
INSERT INTO medium_strings SELECT repeat('k', 122879);
statement ok
INSERT INTO medium_strings SELECT range::VARCHAR::BLOB FROM range(100000);
statement ok
INSERT INTO medium_strings SELECT repeat('k', 122879);
statement ok
INSERT INTO medium_strings SELECT range::VARCHAR::BLOB || 'other' FROM range(100000);
statement ok
INSERT INTO medium_strings SELECT repeat('k', 122879);
statement ok
CREATE INDEX idx ON medium_strings(id);

View File

@@ -0,0 +1,90 @@
# name: test/sql/index/art/create_drop/test_art_many_versions.test
# description: Test ART index creation with many versions
# group: [create_drop]
statement ok
SET immediate_transaction_mode=true
statement ok
PRAGMA enable_verification
# insert the values [1...20001]
statement ok con1
CREATE TABLE integers(i INTEGER)
statement ok con1
INSERT INTO integers SELECT * FROM range(1, 20001, 1)
# now start a transaction in con2
statement ok con2
BEGIN TRANSACTION
# increment values by 1
statement ok con1
UPDATE integers SET i=i+1
# now start a transaction in con3
statement ok con3
BEGIN TRANSACTION
# increment values by 1 again
statement ok con1
UPDATE integers SET i=i+1
# now start a transaction in con4
statement ok con4
BEGIN TRANSACTION
# increment values by 1 again
statement ok con1
UPDATE integers SET i=i+1
# create an index, this fails because we have outstanding updates
statement error con1
CREATE INDEX i_index ON integers using art(i)
----
# con2
query R con2
SELECT SUM(i) FROM integers
----
200010000.000000
query R con2
SELECT SUM(i) FROM integers WHERE i > 0
----
200010000.000000
# con3
query R con3
SELECT SUM(i) FROM integers
----
200030000.000000
query R con3
SELECT SUM(i) FROM integers WHERE i > 0
----
200030000.000000
# con4
query R con4
SELECT SUM(i) FROM integers
----
200050000.000000
query R con4
SELECT SUM(i) FROM integers WHERE i > 0
----
200050000.000000
# total sum
query R con1
SELECT SUM(i) FROM integers
----
200070000.000000
query R con1
SELECT SUM(i) FROM integers WHERE i > 0
----
200070000.000000

View File

@@ -0,0 +1,61 @@
# name: test/sql/index/art/create_drop/test_art_single_value.test
# description: Test an ART containing a single value
# group: [create_drop]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
CREATE INDEX i_index ON integers using art(i)
statement ok
INSERT INTO integers VALUES (1)
query I
SELECT * FROM integers WHERE i < 3
----
1
query I
SELECT * FROM integers WHERE i <= 1
----
1
query I
SELECT * FROM integers WHERE i > 0
----
1
query I
SELECT * FROM integers WHERE i >= 1
----
1
query I
SELECT * FROM integers WHERE i = 1
----
1
query I
SELECT * FROM integers WHERE i < 1
----
query I
SELECT * FROM integers WHERE i <= 0
----
query I
SELECT * FROM integers WHERE i > 1
----
query I
SELECT * FROM integers WHERE i >= 2
----
query I
SELECT * FROM integers WHERE i = 2
----

View File

@@ -0,0 +1,188 @@
# name: test/sql/index/art/insert_update_delete/test_art_linear_insert.test_slow
# description: Test ART index with linear insertions and deletes
# group: [insert_update_delete]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER);
statement ok
CREATE INDEX i_index ON integers using art(i);
# this test tests linear insertions into the ART index
# we test using a number of different "breaking points":
# 4, 16, 48, 256, 1024
# this is related to the ART leaf size
# BREAKING POINT: [4]
loop i 1 5
statement ok
INSERT INTO integers VALUES (${i});
# verify the element was inserted correctly
query I
SELECT COUNT(*)-${i} FROM integers WHERE i < 100000000;
----
0
query I
SELECT COUNT(*)-${i} FROM integers WHERE i >= 0;
----
0
endloop
# now delete data sequentially
loop i 1 5
statement ok
DELETE FROM integers WHERE i=${i};
# verify that the deletion worked
query I
SELECT COUNT(*)+${i} FROM integers WHERE i >= 0;
----
4
endloop
# BREAKING POINT: [16]
loop i 1 17
statement ok
INSERT INTO integers VALUES (${i});
# verify the element was inserted correctly
query I
SELECT COUNT(*)-${i} FROM integers WHERE i < 100000000;
----
0
query I
SELECT COUNT(*)-${i} FROM integers WHERE i >= 0;
----
0
endloop
# now delete data sequentially
loop i 1 17
statement ok
DELETE FROM integers WHERE i=${i};
# verify that the deletion worked
query I
SELECT COUNT(*)+${i} FROM integers WHERE i >= 0;
----
16
endloop
# BREAKING POINT: [48]
loop i 1 49
statement ok
INSERT INTO integers VALUES (${i});
# verify the element was inserted correctly
query I
SELECT COUNT(*)-${i} FROM integers WHERE i < 100000000;
----
0
query I
SELECT COUNT(*)-${i} FROM integers WHERE i >= 0;
----
0
endloop
# now delete data sequentially
loop i 1 49
statement ok
DELETE FROM integers WHERE i=${i};
# verify that the deletion worked
query I
SELECT COUNT(*)+${i} FROM integers WHERE i >= 0;
----
48
endloop
# BREAKING POINT: [256]
loop i 1 257
statement ok
INSERT INTO integers VALUES (${i});
# verify the element was inserted correctly
query I
SELECT COUNT(*)-${i} FROM integers WHERE i < 100000000;
----
0
query I
SELECT COUNT(*)-${i} FROM integers WHERE i >= 0;
----
0
endloop
# now delete data sequentially
loop i 1 257
statement ok
DELETE FROM integers WHERE i=${i};
# verify that the deletion worked
query I
SELECT COUNT(*)+${i} FROM integers WHERE i >= 0;
----
256
endloop
# BREAKING POINT: [1024]
loop i 1 1025
statement ok
INSERT INTO integers VALUES (${i});
# verify the element was inserted correctly
query I
SELECT COUNT(*)-${i} FROM integers WHERE i < 100000000;
----
0
query I
SELECT COUNT(*)-${i} FROM integers WHERE i >= 0;
----
0
endloop
# now delete data sequentially
loop i 1 1025
statement ok
DELETE FROM integers WHERE i=${i};
# verify that the deletion worked
query I
SELECT COUNT(*)+${i} FROM integers WHERE i >= 0;
----
1024
endloop

View File

@@ -0,0 +1,38 @@
# name: test/sql/index/art/insert_update_delete/test_art_non_linear_insertion.test_slow
# description: Test Anon-linear insertions into an ART
# group: [insert_update_delete]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
CREATE INDEX i_index ON integers using art(i)
# non-linear insertion
loop i 0 5
# insert the even values between 0 and 1000
# 0..2..4..6..998
statement ok
INSERT INTO integers SELECT * FROM range(0, 1000, 2)
# insert the uneven values between 0 and 1000
# 1..3..5..7..999
statement ok
INSERT INTO integers SELECT * FROM range(0, 1000, 2)
endloop
query I
SELECT COUNT(*) FROM integers
----
5000
query I
SELECT COUNT(*) FROM integers WHERE i < 1000000
----
5000

View File

@@ -0,0 +1,36 @@
# name: test/sql/index/art/insert_update_delete/test_art_parallel_updates.test_slow
# description: Test concurrent updates causing index scans.
# group: [insert_update_delete]
unzip data/storage/artupdates.db.gz __TEST_DIR__/artupdates.db
statement ok
ATTACH '__TEST_DIR__/artupdates.db' AS db;
statement ok
USE db;
statement ok
BEGIN TRANSACTION;
loop i 0 100
statement ok
UPDATE test SET importId = 725 WHERE id = 34165;
statement ok
UPDATE test SET importId = 663 WHERE id = 42638;
statement ok
UPDATE test SET importId = 210 WHERE id = 11288;
statement ok
UPDATE test SET importId = 805 WHERE id = 764;
statement ok
UPDATE test SET importId = 782 WHERE id = 10151;
statement ok
UPDATE test SET importId = 53 WHERE id = 3229;
endloop

View File

@@ -0,0 +1,51 @@
# name: test/sql/index/art/insert_update_delete/test_art_random_deletion.test_slow
# description: Test ART index with a random deletion
# group: [insert_update_delete]
statement ok
CREATE TABLE integers(i INTEGER);
statement ok
CREATE INDEX i_index ON integers using art(i);
loop i 0 2048
statement ok
INSERT INTO integers VALUES (${i} * ${i});
query I
select COUNT(*) - ${i} - 1 FROM integers WHERE i >= 0;
----
0
endloop
# test that the insertions worked
query I
select COUNT(*) FROM integers WHERE i >= 0;
----
2048
# delete data in a random order
loop i 0 2048
# delete one integer, randomly selected
statement ok
DELETE FROM integers WHERE i=(SELECT i FROM integers ORDER BY RANDOM() LIMIT 1);
# verify the table count
query I
SELECT COUNT(*) + ${i} + 1 FROM integers
----
2048
query I
SELECT COUNT(*) + ${i} + 1 FROM integers WHERE i>= 0
----
2048
endloop

View File

@@ -0,0 +1,93 @@
# name: test/sql/index/art/insert_update_delete/test_art_sel_vector.test
# description: Test ART usage with selection vectors
# group: [insert_update_delete]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE source(i INTEGER)
statement ok
INSERT INTO source VALUES (1), (2), (3), (4), (5), (6)
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
CREATE INDEX i_index ON integers using art(i)
# insert with selection vector
statement ok
INSERT INTO integers SELECT * FROM source WHERE i % 2 = 0
query I
SELECT * FROM integers WHERE i<3 ORDER BY 1
----
2
query I
SELECT * FROM integers ORDER BY 1
----
2
4
6
query I
SELECT * FROM integers WHERE i>3 ORDER BY 1
----
4
6
query I
SELECT * FROM integers WHERE i<=3 ORDER BY 1
----
2
query I
SELECT * FROM integers WHERE i>=3 ORDER BY 1
----
4
6
# update with selection vector
statement ok
UPDATE integers SET i=3 WHERE i=4
query I
SELECT * FROM integers WHERE i<3 ORDER BY 1
----
2
query I
SELECT * FROM integers WHERE i<=3 ORDER BY 1
----
2
3
query I
SELECT * FROM integers WHERE i>3 ORDER BY 1
----
6
query I
SELECT * FROM integers WHERE i>=3 ORDER BY 1
----
3
6
# delete with selection vector
statement ok
DELETE FROM integers WHERE i>3
query I
SELECT * FROM integers WHERE i > 0 ORDER BY 1
----
2
3
query I
SELECT * FROM integers WHERE i < 3 ORDER BY 1
----
2

View File

@@ -0,0 +1,45 @@
# name: test/sql/index/art/insert_update_delete/test_art_simple_update.test
# description: Test simple updates on the ART
# group: [insert_update_delete]
statement ok
PRAGMA enable_verification
statement ok con1
CREATE TABLE integers(i INTEGER)
statement ok con1
CREATE INDEX i_index ON integers using art(i)
statement ok con1
INSERT INTO integers VALUES (1)
statement ok con1
BEGIN TRANSACTION
statement ok con1
UPDATE integers SET i=10 WHERE i=1
# con sees the new state
query I con1
SELECT * FROM integers WHERE i < 5
----
query I con1
SELECT * FROM integers WHERE i > 0
----
10
# con2 sees the old state
query I con2
SELECT * FROM integers WHERE i < 5
----
1
query I con2
SELECT * FROM integers WHERE i > 0
----
1
statement ok con1
ROLLBACK

View File

@@ -0,0 +1,29 @@
# name: test/sql/index/art/insert_update_delete/test_art_update.test
# description: Test updates on the ART
# group: [insert_update_delete]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
CREATE INDEX i_index ON integers using art(j)
statement ok
INSERT INTO integers VALUES (1, 2), (2, 2)
statement ok
UPDATE integers SET j=10 WHERE i=1
statement ok
UPDATE integers SET j=10 WHERE rowid=0
statement ok
DELETE FROM integers WHERE rowid=1
query II
SELECT * FROM integers WHERE j>5
----
1 10

View File

@@ -0,0 +1,130 @@
# name: test/sql/index/art/insert_update_delete/test_art_update_other_column.test
# description: Test an ART index on a table with updates to other columns
# group: [insert_update_delete]
statement ok
PRAGMA enable_verification
statement ok con1
CREATE TABLE integers(i BIGINT, j INTEGER, k VARCHAR)
statement ok con1
CREATE INDEX i_index ON integers using art(j)
statement ok con1
INSERT INTO integers VALUES (10, 1, 'hello'), (11, 2, 'world')
# condition on "j"
query IIT con1
SELECT * FROM integers WHERE j=1
----
10 1 hello
# now update the column
statement ok con2
BEGIN TRANSACTION
statement ok con2
UPDATE integers SET i=100, k='update' WHERE j=1
# con sees the old state, con2 sees the new state
query IIT con1
SELECT * FROM integers WHERE j=1
----
10 1 hello
query IIT con2
SELECT * FROM integers WHERE j=1
----
100 1 update
# after a commit, both see the new state
statement ok con2
COMMIT
query IIT con1
SELECT * FROM integers WHERE j=1
----
100 1 update
query IIT con2
SELECT * FROM integers WHERE j=1
----
100 1 update
# now do the same but with two outstanding updates
statement ok con1
BEGIN TRANSACTION
statement ok con2
BEGIN TRANSACTION
statement ok con1
UPDATE integers SET i=20, k='t1' WHERE j=1
statement ok con2
UPDATE integers SET i=21, k='t2' WHERE j=2
# con1 sees the updated state for the first tuple, but the old state for the new tuple
query IIT con1
SELECT * FROM integers WHERE j=1
----
20 1 t1
query IIT con1
SELECT * FROM integers WHERE j=2
----
11 2 world
query IIT con1
SELECT * FROM integers ORDER BY j
----
20 1 t1
11 2 world
# con2 sees the updated state for the second tuple, but the old state for the new tuple
query IIT con2
SELECT * FROM integers WHERE j=1
----
100 1 update
query IIT con2
SELECT * FROM integers WHERE j=2
----
21 2 t2
query IIT con2
SELECT * FROM integers ORDER BY j
----
100 1 update
21 2 t2
# after commit, both see the updated state
statement ok con1
COMMIT
statement ok con2
COMMIT
query IIT con1
SELECT * FROM integers WHERE j=1
----
20 1 t1
query IIT con1
SELECT * FROM integers WHERE j=2
----
21 2 t2
query IIT con1
SELECT * FROM integers ORDER BY j
----
20 1 t1
21 2 t2
query IIT con2
SELECT * FROM integers ORDER BY j
----
20 1 t1
21 2 t2

View File

@@ -0,0 +1,69 @@
# name: test/sql/index/art/insert_update_delete/test_art_update_same_value.test
# description: Test the ART index with multiple updates on the same value
# group: [insert_update_delete]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
CREATE INDEX i_index ON integers using art(i)
statement ok
INSERT INTO integers VALUES (1)
query I
SELECT * FROM integers WHERE i > 0
----
1
# update the same tuple a bunch of times in the same transaction and then rollback
statement ok
BEGIN TRANSACTION
loop i 1 11
statement ok
UPDATE integers SET i=${i}+1 WHERE i=${i};
query I
SELECT COUNT(*) FROM (SELECT * FROM integers WHERE i > 0 EXCEPT SELECT ${i} + 1) t1;
----
0
endloop
statement ok
ROLLBACK
query I
SELECT * FROM integers WHERE i > 0
----
1
# now update the same tuple a bunch of times in the same transaction and then commit
statement ok
BEGIN TRANSACTION
loop i 1 11
statement ok
UPDATE integers SET i=${i}+1 WHERE i=${i};
query I
SELECT COUNT(*) FROM (SELECT * FROM integers WHERE i > 0 EXCEPT SELECT ${i} + 1) t1;
----
0
endloop
statement ok
COMMIT
query I
SELECT * FROM integers WHERE i > 0
----
11

View File

@@ -0,0 +1,87 @@
# name: test/sql/index/art/insert_update_delete/test_art_update_scans.test_slow
# description: Test mixing updates, insertions, deletions and big scans
# group: [insert_update_delete]
statement ok
PRAGMA enable_verification
statement ok
BEGIN TRANSACTION
statement ok
CREATE TABLE integers(i integer)
statement ok
CREATE INDEX i_index ON integers(i)
statement ok
INSERT INTO integers SELECT * FROM range(1, 25001, 1)
statement ok
COMMIT
# check the sum and the count
query RI
SELECT SUM(i), COUNT(i) FROM integers WHERE i>0
----
312512500 25000
query II
SELECT MIN(i), MAX(i) FROM integers ORDER BY 1
----
1 25000
# update the data with an index scan
query I
UPDATE integers SET i=i+1 WHERE i>0
----
25000
query II
SELECT MIN(i), MAX(i) FROM integers ORDER BY 1
----
2 25001
query I
SELECT COUNT(DISTINCT i) FROM integers ORDER BY 1
----
25000
# now check the sum and the count again
query RI
SELECT SUM(i), COUNT(i) FROM integers WHERE i>0
----
312537500 25000
# now delete from the table with an index scan
query I
DELETE FROM integers WHERE i>0
----
25000
query RI
SELECT SUM(i), COUNT(i) FROM integers WHERE i>0
----
NULL 0
statement ok
create table test_int(i integer primary key);
statement ok
insert into test_int select * from range(1000000);
query I
select count(*) from test_int;
----
1000000
statement ok
delete from test_int;
statement ok
insert into test_int select * from range(1000000);
query I
select count(*) from test_int;
----
1000000

View File

@@ -0,0 +1,79 @@
# name: test/sql/index/art/issues/test_art_fuzzer.test
# description: Test different ART fuzzer issues
# group: [issues]
# issue 5984, number 21
statement ok
CREATE TABLE t1 (c1 DECIMAL(4, 3));
statement ok
INSERT INTO t1(c1) VALUES (1), (-0.505);
statement ok
CREATE INDEX i1 ON t1 (TRY_CAST(c1 AS USMALLINT));
statement ok
INSERT INTO t1(c1) VALUES (2), (3);
# issue 5984, number 22
statement ok
CREATE TABLE t2 (c1 VARCHAR);
statement ok
CREATE INDEX i2 ON t2 (c1);
statement ok
INSERT INTO t2 VALUES (decode('g\x00'::BLOB)::VARCHAR),('g');
statement ok
INSERT INTO t2 VALUES ('\0');
statement ok
CREATE INDEX i22 ON t2 (c1);
# issue 5984, number 32
statement ok
CREATE TABLE t3(c1 INT);
statement ok
INSERT INTO t3 VALUES (0), (85491);
statement ok
CREATE INDEX i3 ON t3 (c1, (TRY_CAST(c1 AS USMALLINT)));
# issue 5984, number 44
statement ok
CREATE TABLE t4 (c1 BOOLEAN);
statement ok
CREATE INDEX i4 ON t4 (c1);
statement ok
INSERT INTO t4 VALUES (1), (0), (1), (1);
statement ok
UPDATE t4 SET c1 = NULL;
# issue 5984, number 19
statement ok
CREATE TABLE t_leak (c1 INT);
statement ok
INSERT INTO t_leak VALUES (2), (1), (1), (540000);
statement error
CREATE UNIQUE INDEX i_leak ON t_leak (c1);
----
Constraint Error: Data contains duplicates on indexed column(s)
# issue 5984, number 22
statement ok
CREATE TABLE t21 (c1 INT);
statement ok
CREATE INDEX i21 ON t21 (c1, "decode"('\x00'::BLOB));
statement ok
INSERT INTO t21 VALUES (1);

View File

@@ -0,0 +1,23 @@
# name: test/sql/index/art/issues/test_art_fuzzer_persisted.test
# description: Test ART fuzzer issue with persisted database
# group: [issues]
# issue 5984, number 41
# load the DB from disk
load __TEST_DIR__/create_idx.db
statement ok
CREATE TABLE t1 AS (SELECT 1 c1, 'a' c2);
statement ok
CREATE INDEX i1 ON t1 (c1);
statement ok
PRAGMA MEMORY_LIMIT='4MB';
statement ok
CHECKPOINT;
statement ok
INSERT INTO t1(c2) (SELECT DISTINCT 'b');

View File

@@ -0,0 +1,70 @@
# name: test/sql/index/art/issues/test_art_internal_issue_4742.test
# description: Test that Index Scan is triggered even when there is a nested conjunction filter on the index column
# group: [issues]
# needs this vector size otherwise the sample is somehow not repeatable
require vector_size 2048
statement ok
create or replace table test as select 9223372036854776 + range * 9223372036854776 i from range(100);
statement ok
create index my_index on test(i);
# this already worked properly, uses an index scan
query II
explain analyze select i from test SEMI JOIN (select i from test using sample reservoir(10) repeatable (42)) USING (i);
----
analyzed_plan <REGEX>:.*Index Scan.*
# should return exactly 10 values, as we join with a sample of size 10 of itself
query I
select count(*) from test SEMI JOIN (select i from test using sample reservoir(10) repeatable (42)) USING (i);
----
10
# given the seed, the return values should be stable
query I
select i from test SEMI JOIN (select i from test using sample reservoir(10) repeatable (42)) USING (i) order by all;
----
36893488147419104
138350580552821640
184467440737095520
249031044995078952
295147905179352832
433498485732174472
682529530727253424
700976274800962976
839326855353784616
903890459611768048
# this did not work properly before the fix: doing the same join with a table
statement ok
create or replace table sample as select i from test using sample reservoir(10) repeatable (42);
# should also use an index scan now
query II
explain analyze select i from test SEMI JOIN sample USING (i);
----
analyzed_plan <REGEX>:.*Index Scan.*
# again should be 10 values
query I
select count(*) from test SEMI JOIN sample USING (i);
----
10
# values should be exactly the same as before
query I
select i from test SEMI JOIN sample USING (i) order by all;
----
36893488147419104
138350580552821640
184467440737095520
249031044995078952
295147905179352832
433498485732174472
682529530727253424
700976274800962976
839326855353784616
903890459611768048

View File

@@ -0,0 +1,15 @@
# name: test/sql/index/art/issues/test_art_issue_4976.test
# description: Test CREATE INDEX on default timestamp column
# group: [issues]
statement ok
CREATE TABLE t0(c0 DOUBLE, c1 TIMESTAMP DEFAULT(TIMESTAMP '1970-01-04 12:58:32'));
statement ok
INSERT INTO t0(c1, c0) VALUES (TIMESTAMP '1969-12-28 23:02:08', 1);
statement ok
INSERT INTO t0(c0) VALUES (DEFAULT);
statement ok
CREATE INDEX i2 ON t0(c1, c0);

View File

@@ -0,0 +1,44 @@
# name: test/sql/index/art/issues/test_art_issue_6603.test
# description: Test index join issue 6603
# group: [issues]
statement ok
BEGIN;
statement ok
CREATE TABLE path (
it INTEGER,
x0 TEXT NOT NULL,
x1 TEXT NOT NULL
);
statement ok
CREATE SEQUENCE seq;
statement ok
CREATE TABLE edge (
id INTEGER DEFAULT nextval('seq'),
it INTEGER DEFAULT 0,
x0 TEXT,
x1 TEXT
);
statement ok
CREATE INDEX edge1_idx ON edge (x1);
statement ok
INSERT INTO edge (x0, x1) VALUES ('n2880','n3966');
statement ok
COMMIT;
statement ok
BEGIN;
statement ok
INSERT INTO path SELECT 1, y0, y1 FROM (SELECT DISTINCT edge0.x0 AS y0, edge0.x1 AS y1 FROM edge AS edge0 WHERE edge0.it = 0 AND true AND NOT EXISTS (SELECT * from path AS pre WHERE pre.x0 = edge0.x0 AND pre.x1 = edge0.x1));
query III
SELECT 1, y0, y1 FROM (SELECT DISTINCT edge0.x0 AS y0, path1.x1 AS y1 FROM edge AS edge0,path AS path1 WHERE edge0.it = 0 AND edge0.x1 = path1.x0 AND NOT EXISTS (SELECT * from path AS pre WHERE pre.x0 = edge0.x0 AND pre.x1 = path1.x1));
----

View File

@@ -0,0 +1,29 @@
# name: test/sql/index/art/issues/test_art_issue_6799.test
# description: Test index join issue 6799
# group: [issues]
statement ok
CREATE TABLE key_value_pairs (key VARCHAR PRIMARY KEY, value VARCHAR)
statement ok
INSERT INTO key_value_pairs
SELECT concat('key_', i::VARCHAR), concat('value_', i::VARCHAR)
FROM range(10000) t(i)
WHERE random() < 0.5
statement ok
CREATE TABLE keys_to_lookup (key VARCHAR PRIMARY KEY)
statement ok
INSERT INTO keys_to_lookup
SELECT concat('key_', i::VARCHAR)
FROM range(100) t(i)
statement ok
SELECT COUNT(*) FROM
(
SELECT key, value
FROM
keys_to_lookup
JOIN key_value_pairs USING(key)
)

View File

@@ -0,0 +1,80 @@
# name: test/sql/index/art/issues/test_art_issue_7349.test
# description: Test ensuring that we do not rollback twice when throwing an exception during commit
# group: [issues]
# setting up the different tables and the UNIQUE index
statement ok
CREATE TABLE td(tz VARCHAR(30) NOT NULL);
statement ok
CREATE UNIQUE INDEX sqlsim0 ON td(tz);
statement ok
CREATE TABLE tab0(c2 DATE NOT NULL);
statement ok
CREATE TABLE tab1(c2 DATE NOT NULL);
statement ok
INSERT INTO td VALUES (date '2008-02-29');
# testing different orders of appending values
# interleaved (original issue example)
statement ok
START TRANSACTION;
statement ok
INSERT INTO td VALUES('2006-12-25');
statement ok
INSERT INTO tab0 VALUES('2006-12-25');
statement error
INSERT INTO td VALUES (date '2008-02-29');
----
<REGEX>:Constraint Error.*violates unique constraint.*
statement ok
COMMIT TRANSACTION;
# three tables
statement ok
START TRANSACTION;
statement ok
INSERT INTO tab0 VALUES('2006-12-25');
statement error
INSERT INTO td VALUES (date '2008-02-29');
----
<REGEX>:Constraint Error.*violates unique constraint.*
statement ok
COMMIT TRANSACTION;
statement ok
INSERT INTO tab1 VALUES('2006-12-25');
# other table first
statement ok
START TRANSACTION;
statement ok
INSERT INTO tab0 VALUES('2006-12-25');
statement ok
INSERT INTO td VALUES('2006-12-25');
statement ok
COMMIT TRANSACTION;
query I
SELECT tz FROM td ORDER BY tz;
----
2006-12-25
2008-02-29

View File

@@ -0,0 +1,15 @@
# name: test/sql/index/art/issues/test_art_issue_7530.test
# description: Test to ensure correct multi-value leaf deletions
# group: [issues]
statement ok
CREATE TABLE t14(c0 BIGINT);
statement ok
INSERT INTO t14(c0) VALUES ((1)), ((1)), ((1));
statement ok
CREATE INDEX i1 ON t14(c0 );
statement ok
DELETE FROM t14 WHERE t14.rowid;

View File

@@ -0,0 +1,13 @@
# name: test/sql/index/art/issues/test_art_issue_8066.test_slow
# description: Test CREATE INDEX on a lot of duplicate values with a persistent DB
# group: [issues]
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE t AS SELECT now() AS d FROM generate_series(1, 218165);
statement ok
CREATE INDEX i ON t(d);
restart

View File

@@ -0,0 +1,48 @@
# name: test/sql/index/art/issues/test_art_view_col_binding.test
# description: Test Index Scan push down against views with reordered projections (issue #17290)
# group: [issues]
statement ok
create or replace table test as (
select
cast(unnest(range(1000)) as varchar) as x,
cast(unnest(range(2000,3000)) as varchar) as y,
cast(unnest(range(3000,4000)) as varchar) as z
);
# test simple permutation of initial table projection
statement ok
create index test_x on test(x);
statement ok
create view test_view as (select z, y, x from test);
query II
explain analyze select * from test_view where x = '525';
----
analyzed_plan <REGEX>:.*Index Scan.*
query III
select z, y, x from test_view where x = '525';
----
3525 2525 525
statement ok
drop index test_x;
# test columnref as a child of function
statement ok
create index test_upper_x on test(upper(x));
query II
explain analyze select * from test_view where upper(x) = '526';
----
analyzed_plan <REGEX>:.*Index Scan.*
query III
select z, y, x from test_view where upper(x) = '526';
----
3526 2526 526
statement ok
drop index test_upper_x;

View File

@@ -0,0 +1,103 @@
# name: test/sql/index/art/memory/test_art_linear.test_slow
# description: Test the memory usage of the ART for linear integer insertions
# group: [memory]
require noforcestorage
require skip_reload
statement ok
PRAGMA enable_verification
# Create a table with a primary key and store the memory usage.
# Verify that the memory stays stable when deleting all entries from the table.
# We keep a single empty buffer alive for each allocator, so we never drop to zero bytes.
statement ok
CREATE TABLE t (i integer PRIMARY KEY);
statement ok
INSERT INTO t SELECT * FROM range(1000000);
statement ok
DELETE FROM t;
statement ok
CREATE TABLE base AS SELECT memory_usage_bytes FROM duckdb_memory() WHERE tag = 'ART_INDEX';
loop i 0 5
statement ok
INSERT INTO t SELECT * FROM range(1000000);
statement ok
DELETE FROM t
query I
SELECT
CASE WHEN current.memory_usage_bytes == base.memory_usage_bytes
THEN true
ELSE concat('Current memory usage ', current.memory_usage_bytes , ' is not equal to base usage ', base.memory_usage_bytes)::UNION(error VARCHAR, b BOOLEAN)
END
FROM duckdb_memory() current, base
WHERE current.tag = 'ART_INDEX';
----
true
endloop
# Index memory usage must return to zero after an explicit vacuum.
statement ok
VACUUM t;
query I
SELECT memory_usage_bytes == 0 FROM duckdb_memory() WHERE tag = 'ART_INDEX';
----
true
statement ok
DROP TABLE t;
# create a table with a primary key and store the memory usage
# now verify that the memory drops, but this time drop the whole table instead of deleting entries from it
statement ok
CREATE TABLE t (i integer PRIMARY KEY);
statement ok
INSERT INTO t SELECT * FROM range(1000000);
statement ok
DROP TABLE t;
query I
SELECT memory_usage_bytes == 0 FROM duckdb_memory() WHERE tag = 'ART_INDEX';
----
true
# create a table with a primary key and store the memory usage
# verify that the memory decreases by approximately half when deleting half the entries
statement ok
CREATE TABLE t (i integer PRIMARY KEY);
statement ok
INSERT INTO t SELECT * FROM range(1000000);
statement ok
CREATE TABLE full_idx AS SELECT memory_usage_bytes FROM duckdb_memory() WHERE tag = 'ART_INDEX';
statement ok
DELETE FROM t WHERE i > 500000;
query I
SELECT
CASE WHEN current.memory_usage_bytes <= full_idx.memory_usage_bytes * 0.6
THEN true
ELSE concat('Current memory usage ', current.memory_usage_bytes , ' is not equal to base usage ', full_idx.memory_usage_bytes)::UNION(error VARCHAR, b BOOLEAN)
END
FROM duckdb_memory() current, full_idx
WHERE current.tag = 'ART_INDEX';
----
true

View File

@@ -0,0 +1,108 @@
# name: test/sql/index/art/memory/test_art_non_linear.test_slow
# description: Test the memory usage of the ART for various workloads
# group: [memory]
require skip_reload
statement ok
PRAGMA enable_verification;
statement ok
CREATE FUNCTION mem_to_bytes(x) AS CASE
WHEN CONTAINS(x, 'KiB') THEN REPLACE(x, 'KiB', '')::INT * 1024.0
WHEN CONTAINS(x, 'MiB') THEN REPLACE(x, 'MiB', '')::INT * 1024.0 * 1024
WHEN CONTAINS(x, 'GiB') THEN REPLACE(x, 'GiB', '')::INT * 1024.0 * 1024 * 1024
WHEN CONTAINS(x, 'TiB') THEN REPLACE(x, 'TiB', '')::INT * 1024.0 * 1024 * 1024 * 1024
WHEN x = '0 bytes' THEN 0
ELSE x::INT END;
# test 100K short strings
statement ok
CREATE TABLE strings_temp AS
SELECT ((i * 95823983533) % 100000)::VARCHAR AS s1,
((i * 547892347987) % 1000)::VARCHAR AS s2,
((i * 847892347987) % 100)::VARCHAR AS s3,
FROM range(100000) tbl(i);
statement ok
CREATE TABLE art AS SELECT s1 || 'a' || s2 || 'b' || s3 || 'c' AS id FROM strings_temp;
statement ok
DROP TABLE strings_temp;
statement ok
CREATE INDEX idx ON art USING ART(id);
query I
SELECT mem_to_bytes(memory_usage) < 7500000 FROM pragma_database_size();
----
true
statement ok
DROP TABLE art;
# test 100K long strings
statement ok
CREATE TABLE strings_temp AS
SELECT ((i * 95823983533) % 100000)::VARCHAR AS s1,
((i * 547892347987) % 1000)::VARCHAR AS s2,
((i * 847892347987) % 100)::VARCHAR AS s3,
FROM range(100000) tbl(i);
statement ok
CREATE TABLE art AS SELECT s3 || 'a' || s2 || 'b' || s3 || 'c' || repeat(s2, s3::INT) || s1 || 'a' || s3 || 'c' AS id FROM strings_temp;
statement ok
DROP TABLE strings_temp;
statement ok
CREATE INDEX idx ON art USING ART(id);
# 11 blocks for prefixes, 2 blocks for Node4, 6 blocks for Node16,
# 19 blocks * 256KB = 4864KB
# WITHOUT the index, our database size is already approximately 17MB here
query I
SELECT mem_to_bytes(memory_usage) < 23000000 FROM pragma_database_size();
----
true
statement ok
DROP TABLE art;
# test 100K mostly distinct BIGINT keys
statement ok
CREATE TABLE art AS SELECT (range * 9876983769044::INT128 % 10000000)::INT64 AS id FROM range(100000);
statement ok
CREATE INDEX idx ON art USING ART(id);
# 1 block for prefixes, 6 blocks for Node4, 2 blocks for Node256
# 8 blocks * 256KB = 2048KB
query I
SELECT mem_to_bytes(memory_usage) < 4000000 FROM pragma_database_size();
----
true
statement ok
DROP TABLE art;
# test 100K mostly duplicate INTEGER keys
statement ok
CREATE TABLE art AS SELECT (range * 9876983769044::INT128 % 1000)::INT64 AS id FROM range(100000);
statement ok
CREATE INDEX idx ON art USING ART(id);
query I
SELECT mem_to_bytes(memory_usage) < 4000000 FROM pragma_database_size();
----
true
statement ok
DROP TABLE art;

View File

@@ -0,0 +1,76 @@
# name: test/sql/index/art/memory/test_art_varchar.test_slow
# description: Test the memory usage of the ART for a big table with a VARCHAR column
# group: [memory]
# test issue #7760
require 64bit
require vector_size 2048
statement ok
PRAGMA enable_verification
statement ok
CREATE FUNCTION mem_to_bytes(x) AS CASE
WHEN CONTAINS(x, 'KiB') THEN REPLACE(x, 'KiB', '')::INT * 1024.0
WHEN CONTAINS(x, 'MiB') THEN REPLACE(x, 'MiB', '')::INT * 1024.0 * 1024
WHEN CONTAINS(x, 'GiB') THEN REPLACE(x, 'GiB', '')::INT * 1024.0 * 1024 * 1024
WHEN CONTAINS(x, 'TiB') THEN REPLACE(x, 'TiB', '')::INT * 1024.0 * 1024 * 1024 * 1024
WHEN x = '0 bytes' THEN 0::BIGINT
ELSE x::BIGINT END;
# 7200000 unique strings
statement ok
CREATE TABLE art AS
SELECT rpad(((i * 95823983533) % 86000000)::VARCHAR, 10, '-') AS id
FROM range(7200000) tbl(i);
# 2 * 7200k entries
statement ok
INSERT INTO art (SELECT * FROM art);
# 4 * 7200k entries
statement ok
INSERT INTO art (SELECT * FROM art);
# 8 * 7200k entries
statement ok
INSERT INTO art (SELECT * FROM art);
# 86M entries
statement ok
INSERT INTO art (SELECT * FROM art LIMIT 28400000);
query I
SELECT count(*) FROM art;
----
86000000
query I
SELECT COUNT(DISTINCT id) FROM art;
----
7200000
query II
SELECT MIN(length(id)), MAX(length(id)) FROM art;
----
10 10
statement ok
CREATE TABLE base AS
SELECT mem_to_bytes(memory_usage)::BIGINT AS usage FROM pragma_database_size();
statement ok
SET memory_limit='12GB';
statement ok
CREATE INDEX idx ON art USING ART(id);
query I
SELECT mem_to_bytes(current.memory_usage) > base.usage AND
mem_to_bytes(current.memory_usage) < 5 * base.usage
FROM base, pragma_database_size() current;
----
1

View File

@@ -0,0 +1,54 @@
# name: test/sql/index/art/multi_column/test_art_multi_column.test
# description: Test ART index on table with multiple columns
# group: [multi_column]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i BIGINT, j INTEGER, k VARCHAR)
statement ok
CREATE INDEX i_index ON integers using art(j)
statement ok
INSERT INTO integers VALUES (10, 1, 'hello'), (11, 2, 'world')
# condition on "i"
query I
SELECT i FROM integers WHERE i=10
----
10
query IIT
SELECT * FROM integers WHERE i=10
----
10 1 hello
# condition on "j"
query I
SELECT j FROM integers WHERE j=1
----
1
query IIT
SELECT * FROM integers WHERE j=1
----
10 1 hello
# condition on "k"
query T
SELECT k FROM integers WHERE k='hello'
----
hello
query IT
SELECT i, k FROM integers WHERE k='hello'
----
10 hello
query IIT
SELECT * FROM integers WHERE k='hello'
----
10 1 hello

View File

@@ -0,0 +1,88 @@
# name: test/sql/index/art/multi_column/test_art_multi_column.test_slow
# description: Test ART index on table with multiple columns and connections
# group: [multi_column]
statement ok
PRAGMA enable_verification
require skip_reload
# create a table
statement ok con1
CREATE TABLE integers(i INTEGER, j INTEGER);
statement ok con1
CREATE INDEX i_index ON integers using art(i);
statement ok con1
INSERT INTO integers VALUES (1, 3);
loop i 0 3000
query I
SELECT COUNT(*) FROM integers WHERE i=${i} + 10;
----
0
statement ok
INSERT INTO integers VALUES (${i} + 10, ${i} + 12);
query I
SELECT COUNT(*) FROM integers WHERE i=${i} + 10;
----
1
endloop
# both con and con2 start a transaction
statement ok con1
BEGIN TRANSACTION
statement ok con2
BEGIN TRANSACTION
# con2 updates the integers array before index creation
statement ok con2
UPDATE integers SET i=4 WHERE i=1
# con should see the old state
query I con1
SELECT j FROM integers WHERE i=1
----
3
# con2 should see the updated state
query I con2
SELECT j FROM integers WHERE i=4
----
3
# now we commit con
statement ok con1
COMMIT
# con should still see the old state
query I con1
SELECT j FROM integers WHERE i=1
----
3
statement ok con2
COMMIT
# after commit of con2 - con should see the old state
query I con1
SELECT j FROM integers WHERE i=4
----
3
# now we update the index again, this time after index creation
statement ok con2
UPDATE integers SET i=7 WHERE i=4
# the new state should be visible
query I con1
SELECT j FROM integers WHERE i=7
----
3

View File

@@ -0,0 +1,21 @@
# name: test/sql/index/art/multi_column/test_art_multi_predicate.test
# description: Test a point lookup with multiple predicates
# group: [multi_column]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
CREATE INDEX i_index ON integers using art(i)
statement ok
INSERT INTO integers VALUES (1, 2), (1, 3)
query II
SELECT * FROM integers WHERE i = 1 AND j = 2
----
1 2

View File

@@ -0,0 +1,30 @@
# name: test/sql/index/art/nodes/test_art_cyclic_duplicates.test_slow
# description: Test cycling inserts into the ART.
# group: [nodes]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers (i INTEGER);
statement ok
CREATE INDEX i_index ON integers USING art(i);
# Insert duplicates and test the count.
loop i 0 10
statement ok
INSERT INTO integers SELECT range FROM range(100);
loop j 0 40
query I
SELECT COUNT(*) = ${i} + 1 FROM integers WHERE i = ${j};
----
1
endloop
endloop

View File

@@ -0,0 +1,274 @@
# name: test/sql/index/art/nodes/test_art_leaf.test_slow
# description: Test ART leaf containing duplicates on multi column table
# group: [nodes]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers AS SELECT range a, 1 AS b, 1 AS c FROM range(1024)
statement ok
CREATE INDEX b_index ON integers(b)
# verify counts
query I
SELECT sum(b) FROM integers
----
1024
query I
SELECT sum(b) FROM integers WHERE b = 1
----
1024
query I
SELECT sum(b) FROM integers
----
1024
# now delete some elements
statement ok
DELETE FROM integers WHERE a < 100
# verify counts
query I
SELECT COUNT(b) FROM integers
----
924
query I
SELECT COUNT(b) FROM integers WHERE b = 1
----
924
query I
SELECT sum(b) FROM integers
----
924
# now delete more elements
statement ok
DELETE FROM integers WHERE a < 600
# verify counts
query I
SELECT COUNT(b) FROM integers
----
424
query I
SELECT COUNT(b) FROM integers WHERE b = 1
----
424
query I
SELECT sum(b) FROM integers
----
424
# now delete all elements
statement ok
DELETE FROM integers WHERE a < 1024
# verify counts
query I
SELECT COUNT(*) FROM integers
----
0
query I
SELECT COUNT(*) FROM integers WHERE b = 1
----
0
query I
SELECT COUNT(*) FROM integers
----
0
statement ok
DROP INDEX b_index
statement ok
DROP TABLE integers
# test insertion after matching prefixes
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE tbl_leaf_cov (id INTEGER);
statement ok
CREATE INDEX idx_leaf_cov ON tbl_leaf_cov(id);
statement ok
INSERT INTO tbl_leaf_cov VALUES (1), (1);
# testing growing/shrinking leaves
statement ok
CREATE TABLE tbl_grow_shrink (id_var VARCHAR, id_int INTEGER, id_point BIGINT);
statement ok
CREATE INDEX idx_var ON tbl_grow_shrink(id_var);
statement ok
CREATE INDEX idx_int ON tbl_grow_shrink(id_int);
statement ok
CREATE INDEX idx_both ON tbl_grow_shrink(id_var, id_int, id_point);
statement ok
CREATE INDEX idx_point ON tbl_grow_shrink(id_point);
# growing
loop i 0 29
statement ok
INSERT INTO tbl_grow_shrink VALUES ('hello there stranger! :sunshine:', 2, ${i});
query I
SELECT id_var FROM tbl_grow_shrink WHERE rowid = (SELECT min(rowid) FROM tbl_grow_shrink);
----
hello there stranger! :sunshine:
query I
SELECT id_int FROM tbl_grow_shrink WHERE rowid = (SELECT min(rowid) FROM tbl_grow_shrink);
----
2
query I
SELECT count(id_var) FROM tbl_grow_shrink WHERE id_point = ${i};
----
1
restart
query I
SELECT id_var FROM tbl_grow_shrink WHERE rowid = (SELECT min(rowid) FROM tbl_grow_shrink);
----
hello there stranger! :sunshine:
query I
SELECT id_int FROM tbl_grow_shrink WHERE rowid = (SELECT min(rowid) FROM tbl_grow_shrink);
----
2
query I
SELECT count(id_var) FROM tbl_grow_shrink WHERE id_point = ${i};
----
1
endloop
# some more queries
query I
SELECT count(id_var) FROM tbl_grow_shrink;
----
29
query I
SELECT sum(id_int) FROM tbl_grow_shrink;
----
58
restart
query I
SELECT count(id_var) FROM tbl_grow_shrink;
----
29
query I
SELECT sum(id_int) FROM tbl_grow_shrink;
----
58
# shrinking
loop i 0 29
query I
SELECT id_var FROM tbl_grow_shrink WHERE rowid = (SELECT min(rowid) FROM tbl_grow_shrink);
----
hello there stranger! :sunshine:
query I
SELECT id_int FROM tbl_grow_shrink WHERE rowid = (SELECT min(rowid) FROM tbl_grow_shrink);
----
2
query I
SELECT count(id_var) FROM tbl_grow_shrink WHERE id_point = ${i};
----
1
statement ok
DELETE FROM tbl_grow_shrink WHERE rowid = (SELECT min(rowid) FROM tbl_grow_shrink);
restart
endloop
# some final checking
query I
SELECT count(id_var) FROM tbl_grow_shrink;
----
0
query I
SELECT sum(id_int) FROM tbl_grow_shrink;
----
NULL
# merging leaves
statement ok
CREATE TABLE merge_leaf_tbl (id int);
statement ok
INSERT INTO merge_leaf_tbl SELECT range FROM range(2048);
statement ok
INSERT INTO merge_leaf_tbl VALUES (2047);
statement ok
CREATE INDEX idx_merge_leaf_tbl ON merge_leaf_tbl(id);
statement ok
DROP INDEX idx_merge_leaf_tbl;
statement ok
INSERT INTO merge_leaf_tbl VALUES (2047);
statement ok
INSERT INTO merge_leaf_tbl SELECT range + 10000 FROM range(2048);
statement ok
INSERT INTO merge_leaf_tbl SELECT range + 10000 FROM range(2048);
statement ok
CREATE INDEX idx_merge_leaf_tbl ON merge_leaf_tbl(id);
# code coverage of ART consisting of a single leaf
statement ok
CREATE TABLE tbl (i TINYINT);
statement ok
CREATE INDEX idx ON tbl(i);
statement ok
INSERT INTO tbl VALUES (1), (1), (1);

View File

@@ -0,0 +1,88 @@
# name: test/sql/index/art/nodes/test_art_leaf_coverage.test
# description: ART coverage tests for leaves.
# group: [nodes]
# Test the deserialization of leaves.
load __TEST_DIR__/art_vacuum.db
statement ok
CREATE TABLE duplicates (id UBIGINT);
statement ok
INSERT INTO duplicates SELECT range + 500 FROM range(500);
loop i 0 16
statement ok
INSERT INTO duplicates SELECT range FROM range(500);
endloop
statement ok
INSERT INTO duplicates SELECT range + 1000 FROM range(500);
statement ok
CREATE INDEX idx_duplicates ON duplicates(id);
restart
query I
SELECT id FROM duplicates WHERE id = 255;
----
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
# test different paths in the Leaf::Merge functionality
statement ok
CREATE TABLE leaf_merge_1 (id UINT32, id2 INT64);
statement ok
INSERT INTO leaf_merge_1 SELECT range, range FROM range (0, 2048, 1);
statement ok
INSERT INTO leaf_merge_1 SELECT 2047, 2047 FROM range (10);
statement ok
CREATE INDEX idx_merge_1 ON leaf_merge_1(id, id2);
statement ok
CREATE TABLE leaf_merge_2 (id UINT32, id2 INT64);
statement ok
INSERT INTO leaf_merge_2 SELECT range, range FROM range (0, 2048, 1);
statement ok
INSERT INTO leaf_merge_2 VALUES (2047, 2047)
statement ok
CREATE INDEX idx_merge_2 ON leaf_merge_2(id, id2);
# test merging leaves with same key
statement ok
CREATE TABLE tbl_dup_ser (id INTEGER);
statement ok
INSERT INTO tbl_dup_ser SELECT range FROM range(2043);
statement ok
INSERT INTO tbl_dup_ser SELECT 12345 FROM range(11);
statement ok
CREATE INDEX idx_dup_ser ON tbl_dup_ser(id);

View File

@@ -0,0 +1,154 @@
# name: test/sql/index/art/nodes/test_art_leaf_with_duplicates.test_slow
# description: Test ART leaf containing duplicates
# group: [nodes]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i integer)
statement ok
CREATE INDEX i_index ON integers(i)
# insert 4 elements
statement ok
INSERT INTO integers SELECT 1 FROM range(4)
# verify counts
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
4
# verify sums
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
4
# now delete all elements
statement ok
DELETE FROM integers WHERE i = 1
# verify counts
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
0
query I
SELECT COUNT(*) FROM integers
----
0
# insert 1024 elements
statement ok
INSERT INTO integers SELECT 1 FROM range(1024);
# verify counts
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1024
# verify sums
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
1024
# now delete all elements
statement ok
DELETE FROM integers WHERE i = 1
# verify counts
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
0
query I
SELECT COUNT(*) FROM integers
----
0
# insert 3000 elements: 1
statement ok
INSERT INTO integers SELECT 1 FROM range(3000);
# insert 1024 elements: 2
statement ok
INSERT INTO integers SELECT 2 FROM range(1024);
# verify counts
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
3000
query I
SELECT COUNT(*) FROM integers WHERE i = 2
----
1024
query I
SELECT COUNT(*) FROM integers WHERE i <= 2
----
4024
# verify sums
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
5048
# now delete all elements: 2
statement ok
DELETE FROM integers WHERE i = 2
# verify counts
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
3000
query I
SELECT COUNT(*) FROM integers
----
3000
# now delete all elements: 1
statement ok
DELETE FROM integers WHERE i = 1
# verify counts
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
0
query I
SELECT COUNT(*) FROM integers
----
0
statement ok
DROP INDEX i_index
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,63 @@
# name: test/sql/index/art/nodes/test_art_node_16.test
# description: Test ART Node 16
# group: [nodes]
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE integers(i integer)
statement ok
CREATE INDEX i_index ON integers(i)
# insert elements
loop i 0 6
statement ok
INSERT INTO integers VALUES (${i} + 1);
endloop
restart
# verify counts
loop i 0 6
query I
SELECT COUNT(*) FROM integers WHERE i = ${i} + 1
----
1
endloop
# verify sums
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
3
query I
SELECT sum(i) FROM integers WHERE i > 4
----
11
# now delete all elements
loop i 0 6
statement ok
DELETE FROM integers WHERE i = ${i} + 1
endloop
statement ok
DELETE FROM integers WHERE i = 0
statement ok
DROP INDEX i_index
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,81 @@
# name: test/sql/index/art/nodes/test_art_node_256.test
# description: Test ART Node 256
# group: [nodes]
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE integers(i integer)
statement ok
CREATE INDEX i_index ON integers(i)
# insert elements
loop i 0 60
statement ok
INSERT INTO integers VALUES (${i} + 1);
endloop
restart
# verify counts
loop i 0 20
query I
SELECT COUNT(*) FROM integers WHERE i = ${i} + 1
----
1
endloop
# verify sums
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
3
query I
SELECT sum(i) FROM integers WHERE i > 15
----
1710
# delete an element and reinsert it
statement ok
DELETE FROM integers WHERE i=16;
statement ok
INSERT INTO integers VALUES (16);
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
3
query I
SELECT sum(i) FROM integers WHERE i > 15
----
1710
# now delete all elements
loop i 0 60
statement ok
DELETE FROM integers WHERE i = ${i} + 1
endloop
statement ok
DELETE FROM integers WHERE i = 0
statement ok
DROP INDEX i_index
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,63 @@
# name: test/sql/index/art/nodes/test_art_node_4.test
# description: Test ART Node 4
# group: [nodes]
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE integers(i integer)
statement ok
CREATE INDEX i_index ON integers(i)
# insert elements
loop i 0 4
statement ok
INSERT INTO integers VALUES (${i} + 1);
endloop
restart
# verify counts
loop i 0 4
query I
SELECT COUNT(*) FROM integers WHERE i = ${i} + 1
----
1
endloop
# verify sums
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
3
query I
SELECT sum(i) FROM integers WHERE i > 1
----
9
# now delete all elements
loop i 0 4
statement ok
DELETE FROM integers WHERE i = ${i} + 1
endloop
statement ok
DELETE FROM integers WHERE i = 0
statement ok
DROP INDEX i_index
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,114 @@
# name: test/sql/index/art/nodes/test_art_node_48.test
# description: Test ART Node 48
# group: [nodes]
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE integers(i integer)
statement ok
CREATE INDEX i_index ON integers(i)
# insert elements
loop i 0 20
statement ok
INSERT INTO integers VALUES (${i} + 1);
endloop
restart
# verify counts
loop i 0 20
query I
SELECT COUNT(*) FROM integers WHERE i = ${i} + 1
----
1
endloop
# verify sums
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
3
query I
SELECT sum(i) FROM integers WHERE i > 15
----
90
# delete an element and reinsert it
statement ok
DELETE FROM integers WHERE i=16;
statement ok
INSERT INTO integers VALUES (16);
query I
SELECT sum(i) FROM integers WHERE i <= 2
----
3
query I
SELECT sum(i) FROM integers WHERE i > 15
----
90
# now delete all elements
loop i 0 20
statement ok
DELETE FROM integers WHERE i = ${i} + 1
endloop
statement ok
DELETE FROM integers WHERE i = 0
statement ok
DROP INDEX i_index
statement ok
DROP TABLE integers
statement ok
CREATE TABLE n48_tbl(i varchar, k integer)
statement ok
INSERT INTO n48_tbl SELECT 'a', range FROM range(10000);
statement ok
INSERT INTO n48_tbl SELECT 'b', range FROM range(25);
statement ok
INSERT INTO n48_tbl SELECT 'c', range FROM range(25);
statement ok
CREATE INDEX n48_tbl_idx ON n48_tbl(i, k);
# test freeing all the children of a Node48
statement ok
CREATE TABLE n48_free (id INTEGER);
statement ok
INSERT INTO n48_free SELECT range % 100 FROM range(2048);
loop i 0 20
statement ok
INSERT INTO n48_free VALUES (${i} + 107);
endloop
statement ok
CREATE INDEX idx_n48_free ON n48_free(id);

View File

@@ -0,0 +1,959 @@
# name: test/sql/index/art/nodes/test_art_prefix_edge_cases.test_slow
# description: Test ART prefix edge cases
# group: [nodes]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i BIGINT)
statement ok
CREATE INDEX i_index ON integers using art(i)
# a bunch of values with different prefixes
statement ok
INSERT INTO integers VALUES (9312908412824241)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers
----
1
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
1
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
0
statement ok
INSERT INTO integers VALUES (-2092042498432234)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers
----
2
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
2
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
1
statement ok
INSERT INTO integers VALUES (1)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers
----
3
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
3
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
2
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
1
statement ok
INSERT INTO integers VALUES (-100)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers
----
4
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
4
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
2
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
2
statement ok
INSERT INTO integers VALUES (0)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers
----
5
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
5
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
3
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
2
statement ok
INSERT INTO integers VALUES (-598538523852390852)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers
----
6
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
6
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
3
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
3
statement ok
INSERT INTO integers VALUES (4298421)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers
----
7
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
7
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
4
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
3
statement ok
INSERT INTO integers VALUES (-498249)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498249
----
1
query I
SELECT COUNT(*) FROM integers
----
8
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
8
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
4
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
4
statement ok
INSERT INTO integers VALUES (9312908412824240)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498249
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824240
----
1
query I
SELECT COUNT(*) FROM integers
----
9
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
9
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
5
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
4
statement ok
INSERT INTO integers VALUES (-2092042498432235)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498249
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824240
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432235
----
1
query I
SELECT COUNT(*) FROM integers
----
10
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
10
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
5
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
5
statement ok
INSERT INTO integers VALUES (2)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498249
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824240
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432235
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 2
----
1
query I
SELECT COUNT(*) FROM integers
----
11
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
11
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
6
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
5
statement ok
INSERT INTO integers VALUES (-101)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498249
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824240
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432235
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 2
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -101
----
1
query I
SELECT COUNT(*) FROM integers
----
12
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
12
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
6
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
6
statement ok
INSERT INTO integers VALUES (-598538523852390853)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498249
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824240
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432235
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 2
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -101
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390853
----
1
query I
SELECT COUNT(*) FROM integers
----
13
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
13
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
6
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
7
statement ok
INSERT INTO integers VALUES (4298422)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498249
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824240
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432235
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 2
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -101
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390853
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298422
----
1
query I
SELECT COUNT(*) FROM integers
----
14
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
14
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
7
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
7
statement ok
INSERT INTO integers VALUES (-498261)
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824241
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432234
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 1
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -100
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 0
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390852
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298421
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498249
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 9312908412824240
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -2092042498432235
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 2
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -101
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -598538523852390853
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = 4298422
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = -498261
----
1
query I
SELECT COUNT(*) FROM integers
----
15
query I
SELECT COUNT(*) FROM integers WHERE i < 9223372036854775808
----
15
query I
SELECT COUNT(*) FROM integers WHERE i >= 0
----
7
query I
SELECT COUNT(*) FROM integers WHERE i < 0
----
8

View File

@@ -0,0 +1,124 @@
# name: test/sql/index/art/nodes/test_art_prefixes.test_slow
# description: Test different ART prefixes
# group: [nodes]
statement ok
PRAGMA enable_verification
# very mixed-length prefixes
statement ok
CREATE TABLE different_prefixes(str VARCHAR);
statement ok
INSERT INTO different_prefixes SELECT 'my first very long prefix that is really very long' || range FROM range(2048);
statement ok
INSERT INTO different_prefixes SELECT (range / 100)::VARCHAR || range::VARCHAR FROM range(2048);
statement ok
INSERT INTO different_prefixes SELECT 'my first very long prefix, the other not quite as long prefix that is still very long' || range FROM range(2048);
statement ok
INSERT INTO different_prefixes SELECT 'my first very long prefix, the other not quite as long prefix that is still very long and even longer omg!' || range FROM range(2048);
statement ok
INSERT INTO different_prefixes SELECT range::VARCHAR || (range + 1)::VARCHAR FROM range(2048);
statement ok
CREATE INDEX idx_different_prefixes ON different_prefixes(str);
statement ok
DELETE FROM different_prefixes
WHERE rowid IN (SELECT rowid FROM different_prefixes LIMIT 1000);
statement ok
DELETE FROM different_prefixes
WHERE rowid IN (SELECT rowid FROM different_prefixes LIMIT 3000);
statement ok
DROP INDEX idx_different_prefixes;
# this time all prefixes are long
statement ok
CREATE TABLE longer_prefixes(str VARCHAR);
statement ok
INSERT INTO longer_prefixes
SELECT 'my first very long prefix that is really very long' || range FROM range(2048);
statement ok
INSERT INTO longer_prefixes
SELECT 'my first very long prefix, the other not quite as long prefix that is still very long' || range FROM range(2048);
statement ok
CREATE INDEX idx_longer_prefixes ON longer_prefixes(str);
query I
SELECT str FROM longer_prefixes
WHERE str = 'my first very long prefix that is really very long77';
----
my first very long prefix that is really very long77
statement ok
DROP INDEX idx_longer_prefixes;
# more distinct prefixes
statement ok
CREATE TABLE distinct_prefixes (str VARCHAR);
statement ok
INSERT INTO distinct_prefixes SELECT
'2022-01-01'::DATE + range::INTEGER * 1000 ||
'1004-02-01'::DATE + range::INTEGER * 100 ||
'.' || '6004-02-01'::DATE + range::INTEGER * 2000
FROM range(100000);
statement ok
CREATE INDEX idx_distinct_prefixes ON distinct_prefixes(str);
statement ok
DROP INDEX idx_distinct_prefixes;
# more mixed-length distinct prefixes
statement ok
CREATE TABLE mixed_distinct_prefixes (str VARCHAR);
statement ok
INSERT INTO mixed_distinct_prefixes SELECT
'2022-01-01'::DATE + range::INTEGER * 1000
FROM range(100000);
statement ok
INSERT INTO mixed_distinct_prefixes SELECT
'2022-01-01'::DATE + range::INTEGER * 1000 ||
'1004-02-01'::DATE + range::INTEGER * 100
FROM range(100000);
statement ok
INSERT INTO mixed_distinct_prefixes SELECT
'2022-01-01'::DATE + range::INTEGER * 1000 ||
'1004-02-01'::DATE + range::INTEGER * 100 ||
'.' || '6004-02-01'::DATE + range::INTEGER * 2000
FROM range(100000);
statement ok
CREATE INDEX idx_mixed_distinct_prefixes ON mixed_distinct_prefixes(str);
statement ok
DELETE FROM mixed_distinct_prefixes
WHERE rowid IN (SELECT rowid FROM mixed_distinct_prefixes LIMIT 1000);
statement ok
DELETE FROM mixed_distinct_prefixes
WHERE rowid IN (SELECT rowid FROM mixed_distinct_prefixes LIMIT 1000);
statement ok
DELETE FROM mixed_distinct_prefixes
WHERE rowid IN (SELECT rowid FROM mixed_distinct_prefixes LIMIT 1000);
statement ok
DROP INDEX idx_mixed_distinct_prefixes;

View File

@@ -0,0 +1,65 @@
# name: test/sql/index/art/nodes/test_art_prefixes_restart.test
# description: Test the (de)serialization of different ART prefixes
# group: [nodes]
load __TEST_DIR__/test_art_prefixes.db
statement ok
CREATE TABLE tbl (id INTEGER);
statement ok
CREATE INDEX idx ON tbl(id);
# insert two children into a Node4
statement ok
INSERT INTO tbl VALUES (1), (2);
restart
# delete one child, the other child will still be serialized
statement ok
DELETE FROM tbl WHERE id = 1;
# now do the same, but with a very long shared prefix
statement ok
CREATE TABLE tbl_varchar (id VARCHAR);
statement ok
CREATE INDEX idx_varchar ON tbl_varchar(id);
# insert two children into a Node4
statement ok
INSERT INTO tbl_varchar VALUES
('hello I am a prefix, and it is a beautiful sommer evening, and the plants are blossoming - 1'),
('hello I am a prefix, and it is a beautiful sommer evening, and the plants are blossoming - 2');
restart
# delete one child, the other child will still be serialized
statement ok
DELETE FROM tbl_varchar
WHERE id = 'hello I am a prefix, and it is a beautiful sommer evening, and the plants are blossoming - 1';
# now we test splitting prefixes
statement ok
DELETE FROM tbl_varchar;
statement ok
INSERT INTO tbl_varchar VALUES ('012345678901234'), ('012345678901235');
# now with serialized prefixes
statement ok
DELETE FROM tbl_varchar;
statement ok
INSERT INTO tbl_varchar VALUES
('0123456789-0123456789-0123456789-0123456789');
restart
statement ok
INSERT INTO tbl_varchar VALUES
('0123456779-0123456789-0123456789-0123456789');

View File

@@ -0,0 +1,25 @@
# name: test/sql/index/art/nodes/test_art_sparse_merge.test
# description: Test sparse row IDs for duplicate keys when merging.
# group: [nodes]
statement ok
CREATE TABLE tbl1 (i INT);
loop i 0 8
statement ok
INSERT INTO tbl1 SELECT range FROM range(50000);
statement ok
DELETE FROM tbl1 WHERE i > 4;
endloop
# Parallel index construction.
statement ok
CREATE INDEX idx ON tbl1(i);
query I
SELECT COUNT(i) FROM tbl1 WHERE i = 1;
----
8

View File

@@ -0,0 +1,64 @@
# name: test/sql/index/art/nodes/test_art_sparse_row_ids.test_slow
# description: Test sparse row IDs for duplicate keys.
# group: [nodes]
statement ok
PRAGMA enable_verification
# We try to create sparse row IDs up to their 4'th byte.
# The maximum value of 3 bytes is 16,777,215.
statement ok
CREATE TABLE tbl1 (i INT);
statement ok
CREATE TABLE tbl2 (i INT);
# Inserting into the index chunk-at-a-time.
statement ok
CREATE INDEX idx2 ON tbl2(i);
loop i 0 100
statement ok
INSERT INTO tbl1 SELECT range FROM range(50000);
statement ok
INSERT INTO tbl2 SELECT range FROM range(50000);
query I
SELECT COUNT(i) = ${i} + 1 FROM tbl2 WHERE i = 96;
----
1
statement ok
DELETE FROM tbl1 WHERE i > 270;
statement ok
DELETE FROM tbl2 WHERE i > 270;
endloop
# Parallel index construction.
statement ok
CREATE INDEX idx ON tbl1(i);
query I
SELECT COUNT(i) FROM tbl1 WHERE i = 49;
----
100
query I
SELECT COUNT(i) FROM tbl2 WHERE i = 49;
----
100
query I
SELECT COUNT(i) FROM tbl1 WHERE rowid = (SELECT MAX(rowid) FROM tbl1);
----
1
query I
SELECT COUNT(i) FROM tbl2 WHERE rowid = (SELECT MAX(rowid) FROM tbl2);
----
1

View File

@@ -0,0 +1,28 @@
# name: test/sql/index/art/scan/test_art_adaptive_scan.test
# description: Test scanning more than standard vector size rows with an index scan.
# group: [scan]
statement ok
CREATE TABLE integers AS SELECT 42 AS i FROM range(2050);
statement ok
INSERT INTO integers SELECT 42 + 1 + range FROM range(5000);
statement ok
CREATE INDEX i_index ON integers USING ART(i);
statement ok
SET index_scan_percentage = 1.0;
statement ok
SET index_scan_max_count = 0;
query II
EXPLAIN ANALYZE SELECT COUNT(i) FROM integers WHERE i = 42;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT COUNT(i) FROM integers WHERE i = 42;
----
2050

View File

@@ -0,0 +1,95 @@
# name: test/sql/index/art/scan/test_art_many_matches.test
# description: Test ART index with many matches
# group: [scan]
statement ok
BEGIN TRANSACTION
# create a table with the values [0, 1, 0, 1, ..., 0, 1]
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
INSERT INTO integers SELECT i FROM RANGE(0, 1024, 1) t2(j), (VALUES (0), (1)) t1(i) ORDER BY j, i;
statement ok
CREATE INDEX i_index ON integers using art(i)
query I
SELECT COUNT(*) FROM integers WHERE i<1
----
1024
query I
SELECT COUNT(*) FROM integers WHERE i<=1
----
2048
query I
SELECT COUNT(*) FROM integers WHERE i=0
----
1024
query I
SELECT COUNT(*) FROM integers WHERE i=1
----
1024
query I
SELECT COUNT(*) FROM integers WHERE i>0
----
1024
query I
SELECT COUNT(*) FROM integers WHERE i>=0
----
2048
statement ok
ROLLBACK
statement ok
BEGIN TRANSACTION
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
INSERT INTO integers SELECT i FROM RANGE(0, 2048, 1) t2(j), (VALUES (0), (1)) t1(i) ORDER BY j, i;
statement ok
CREATE INDEX i_index ON integers using art(i)
query I
SELECT COUNT(*) FROM integers WHERE i<1
----
2048
query I
SELECT COUNT(*) FROM integers WHERE i<=1
----
4096
query I
SELECT COUNT(*) FROM integers WHERE i=0
----
2048
query I
SELECT COUNT(*) FROM integers WHERE i=1
----
2048
query I
SELECT COUNT(*) FROM integers WHERE i>0
----
2048
query I
SELECT COUNT(*) FROM integers WHERE i>=0
----
4096
statement ok
ROLLBACK

View File

@@ -0,0 +1,33 @@
# name: test/sql/index/art/scan/test_art_negative_range_scan.test
# description: Test negative range scans on an ART
# group: [scan]
statement ok
CREATE TABLE integers(i integer)
statement ok
INSERT INTO integers SELECT * FROM range(-500, 500, 1)
statement ok
CREATE INDEX i_index ON integers(i)
query R
SELECT sum(i) FROM integers WHERE i >= -500 AND i <= -498
----
-1497.000000
query R
SELECT sum(i) FROM integers WHERE i >= -10 AND i <= 5
----
-40.000000
query R
SELECT sum(i) FROM integers WHERE i >= 10 AND i <= 15
----
75.000000
statement ok
DROP INDEX i_index
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,83 @@
# name: test/sql/index/art/scan/test_art_null_bytes.test
# description: Test ART keys containing NULL bytes.
# group: [scan]
statement ok
CREATE TABLE varchars(v VARCHAR PRIMARY KEY);
statement ok
INSERT INTO varchars VALUES ('hello'), ('hello' || chr(0)), ('hello' || chr(0) || chr(0)), ('hello' || chr(0) || chr(0) || chr(0));
statement error
INSERT INTO varchars VALUES ('hello' || chr(0) || chr(0) || chr(0));
----
Duplicate key
query I
SELECT * FROM varchars WHERE v = 'hello'
----
hello
query I
SELECT * FROM varchars WHERE v = 'hello' || chr(0)
----
hello\0
query I
SELECT * FROM varchars WHERE v = 'hello' || chr(0) || chr(0)
----
hello\0\0
query I
SELECT * FROM varchars WHERE v = 'hello' || chr(0) || chr(0) || chr(0)
----
hello\0\0\0
statement ok
CREATE TABLE blobs(b BLOB PRIMARY KEY);
statement ok
INSERT INTO blobs VALUES (''), ('\x00'), ('\x01'), ('\x00\x01'), ('\x01\x00'), ('\x01\x01'), ('\x00\x00');
statement error
INSERT INTO blobs VALUES ('\x00\x01');
----
Duplicate key
query I
SELECT * FROM blobs WHERE b = ''
----
(empty)
query I
SELECT * FROM blobs WHERE b = '\x00'
----
\x00
query I
SELECT * FROM blobs WHERE b = '\x00\x01'
----
\x00\x01
query I
SELECT * FROM blobs WHERE b >= '\x00' ORDER BY b::VARCHAR
----
\x00
\x00\x00
\x00\x01
\x01
\x01\x00
\x01\x01
query I
SELECT * FROM blobs WHERE b >= '\x01' ORDER BY b::VARCHAR
----
\x01
\x01\x00
\x01\x01
query I
SELECT * FROM blobs WHERE b >= '\x01\x00' ORDER BY b::VARCHAR
----
\x01\x00
\x01\x01

View File

@@ -0,0 +1,35 @@
# name: test/sql/index/art/scan/test_art_prepared_scan.test
# description: Test the usage of prepared statements for ART index scans
# group: [scan]
statement ok
CREATE TABLE integers(i INTEGER);
statement ok
INSERT INTO integers VALUES (1), (2), (4);
statement ok
CREATE INDEX i_index ON integers(i);
query II
EXPLAIN ANALYZE SELECT i FROM integers WHERE i = 2;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT i FROM integers WHERE i = 2;
----
2
statement ok
PREPARE v1 AS SELECT * FROM integers WHERE i = $1;
query II
EXPLAIN ANALYZE EXECUTE v1(2);
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
EXECUTE v1(2);
----
2

View File

@@ -0,0 +1,86 @@
# name: test/sql/index/art/scan/test_art_range_scan.test
# description: Test ART range scan
# group: [scan]
statement ok
CREATE TABLE test (x VARCHAR PRIMARY KEY);
statement ok
INSERT INTO test VALUES ('abc');
statement ok
INSERT INTO test VALUES ('def');
query I
SELECT * FROM test WHERE x > 'z';
----
statement ok
INSERT INTO test VALUES ('abcd');
query I
SELECT x FROM test WHERE x > 'abce';
----
def
statement ok
DROP TABLE test;
statement ok
CREATE TABLE test (x VARCHAR PRIMARY KEY);
statement ok
INSERT INTO test VALUES ('abcd'), ('abde');
query I
SELECT x FROM test WHERE x > 'abce';
----
abde
statement ok
DROP TABLE test;
statement ok
CREATE TABLE test (x USMALLINT PRIMARY KEY);
# node 48
statement ok
INSERT INTO test SELECT i FROM range(1, 20) tbl(i);
query I
SELECT x FROM test WHERE x > 20;
----
statement ok
INSERT INTO test VALUES (256);
query I
SELECT x FROM test WHERE x > 20;
----
256
statement ok
DROP TABLE test;
statement ok
CREATE TABLE test (x USMALLINT PRIMARY KEY);
# node 256
statement ok
INSERT INTO test SELECT i FROM range(1, 135) tbl(i);
query I
SELECT x FROM test WHERE x > 135;
----
statement ok
INSERT INTO test VALUES (256), (257);
query I
SELECT x FROM test WHERE x > 135;
----
256
257
statement ok
DROP TABLE test;

View File

@@ -0,0 +1,124 @@
# name: test/sql/index/art/scan/test_art_scan_coverage.test
# description: Test edge cases during index scans
# group: [scan]
statement ok
CREATE TABLE tab0(pk INTEGER PRIMARY KEY, col0 INTEGER, col1 FLOAT, col2 TEXT, col3 INTEGER, col4 FLOAT, col5 TEXT)
statement ok
INSERT INTO tab0 VALUES(0,25,74.4,'vvcgn',47,57.68,'ymlye')
statement ok
INSERT INTO tab0 VALUES(1,72,81.64,'zsnbm',42,74.55,'tzagd')
statement ok
INSERT INTO tab0 VALUES(2,45,38.39,'dmsso',87,29.20,'ywydk')
statement ok
INSERT INTO tab0 VALUES(3,81,97.79,'tdbjm',48,89.67,'hvaol')
statement ok
INSERT INTO tab0 VALUES(4,17,18.5,'ddcya',66,87.1,'ndulx')
statement ok
INSERT INTO tab0 VALUES(5,46,83.75,'khqpe',31,31.98,'hzpio')
statement ok
INSERT INTO tab0 VALUES(6,85,8.45,'ugwie',30,22.61,'klsxt')
statement ok
INSERT INTO tab0 VALUES(7,36,54.34,'pflrv',18,61.89,'vrltg')
statement ok
INSERT INTO tab0 VALUES(8,47,41.84,'plpkl',76,65.31,'yzivj')
statement ok
INSERT INTO tab0 VALUES(9,76,63.21,'uakya',80,80.58,'ocfgj')
statement ok
CREATE TABLE tab1(pk INTEGER PRIMARY KEY, col0 INTEGER, col1 FLOAT, col2 TEXT, col3 INTEGER, col4 FLOAT, col5 TEXT)
statement ok
CREATE INDEX idx_tab1_0 on tab1 (col0)
statement ok
CREATE INDEX idx_tab1_1 on tab1 (col1)
statement ok
CREATE INDEX idx_tab1_3 on tab1 (col3)
statement ok
CREATE INDEX idx_tab1_4 on tab1 (col4)
statement ok
INSERT INTO tab1 SELECT * FROM tab0
statement ok
DELETE FROM tab1 WHERE col3 = 54 AND col1 <= 76.83
query I rowsort label-empty
SELECT pk FROM tab1 WHERE col3 = 54 AND col1 <= 76.83
----
query I rowsort label-225
SELECT pk FROM tab1 WHERE NOT (col3 = 54 AND col1 <= 76.83)
----
10 values hashing to e20b902b49a98b1a05ed62804c757f94
statement ok
DELETE FROM tab1 WHERE (col4 > 71.47) OR col0 IN (98,26,25,60)
query I rowsort label-empty
SELECT pk FROM tab1 WHERE (col4 > 71.47) OR col0 IN (98,26,25,60)
----
query I rowsort label-240
SELECT pk FROM tab1 WHERE NOT ((col4 > 71.47) OR col0 IN (98,26,25,60))
----
2
5
6
7
8
statement ok
DELETE FROM tab1 WHERE ((col0 > 32) AND col0 < 87)
query I rowsort label-empty
SELECT pk FROM tab1 WHERE ((col0 > 32) AND col0 < 87)
----
# Issue #13785
statement ok
CREATE TABLE t0_varchar(c0 VARCHAR);
statement ok
INSERT INTO t0_varchar(c0) VALUES ('a'), ('a');
statement ok
CREATE INDEX t0i0_idx ON t0_varchar(c0 );
query I
SELECT c0 FROM t0_varchar WHERE t0_varchar.c0 <= 'a';
----
a
a
# Issue #13842
statement ok
CREATE TABLE t0_scan(c0 DATE);
statement ok
INSERT INTO t0_scan(c0) VALUES ('1970-01-02'), ('1970-01-02'), ('1970-01-03');
statement ok
CREATE INDEX t0i0 ON t0_scan(c0 DESC);
query I
SELECT c0 FROM t0_scan WHERE '1970-01-03' >= t0_scan.c0 ORDER BY c0;
----
1970-01-02
1970-01-02
1970-01-03

View File

@@ -0,0 +1,58 @@
# name: test/sql/index/art/scan/test_art_scan_duplicate_filters.test
# description: Test index scans with duplicate filters.
# group: [scan]
statement ok
CREATE TABLE t_1 (fIdx VARCHAR, sIdx UUID,);
statement ok
CREATE TABLE t_3 (fIdx VARCHAR, sIdx UUID);
statement ok
CREATE TABLE t_4 (sIdx UUID);
statement ok
CREATE TABLE t_5 (sIdx UUID);
statement ok
CREATE UNIQUE INDEX _pk_idx_t_5 ON t_5 (sIdx);
statement ok
INSERT INTO t_4 (sIdx) VALUES
('1381e0ce-6b3e-43f5-9536-5e7af3a512a5'::UUID),
('6880cdba-09f5-3c4f-8eb8-391aefdd8052'::UUID),
('a3e876dd-5e50-3af7-9649-689fd938daeb'::UUID),
('e0abc0d3-63be-41d8-99ca-b1269ed153a8'::UUID);
statement ok
INSERT INTO t_5 (sIdx) VALUES
('a3e876dd-5e50-3af7-9649-689fd938daeb'::UUID),
('e0abc0d3-63be-41d8-99ca-b1269ed153a8'::UUID),
('91c79790-5828-45f2-ad88-50e9b541cc05'::UUID),
('1381e0ce-6b3e-43f5-9536-5e7af3a512a5'::UUID),
('d9f29fa5-2051-3ea4-9d9e-15c3698b4bb8'::UUID),
('6880cdba-09f5-3c4f-8eb8-391aefdd8052'::UUID),
('3239280c-2204-3e60-b3a1-3ad3acc8fd59'::UUID),
('2fced822-342d-344a-aa34-2707e593be52'::UUID);
query I
WITH
cte_5 AS (
SELECT sIdx FROM t_4 ANTI JOIN t_3 USING (sIdx)
),
cte_6 AS MATERIALIZED (
SELECT
COALESCE(cte_5.sIdx, t_1.sIdx) AS sIdx,
COALESCE(t_1.fIdx, cte_5.sIdx::VARCHAR) AS fIdx,
FROM cte_5 FULL JOIN t_1 USING (sIdx)
),
cte_7 AS (
SELECT t_5.sIdx, FROM t_5
WHERE sIdx IN (SELECT sIdx FROM cte_6)
)
SELECT fIdx, FROM cte_6 JOIN cte_7 USING (sIdx) ORDER BY fIdx;
----
1381e0ce-6b3e-43f5-9536-5e7af3a512a5
6880cdba-09f5-3c4f-8eb8-391aefdd8052
a3e876dd-5e50-3af7-9649-689fd938daeb
e0abc0d3-63be-41d8-99ca-b1269ed153a8

View File

@@ -0,0 +1,35 @@
# name: test/sql/index/art/scan/test_art_scan_normal_to_nested.test
# description: Test range scanning with an iterator moving from a normal leaf to a nested leaf.
# group: [scan]
statement ok
CREATE TABLE integers (i BIGINT);
statement ok
CREATE INDEX idx_integers ON integers (i);
statement ok
INSERT INTO integers (i) VALUES ('1'), ('-1'), ('1');
# The border is exactly when moving from a non-nested leaf to a nested leaf.
query I
SELECT i FROM integers WHERE i <= 0;
----
-1
# Issue 16074.
statement ok
CREATE TABLE t0(c1 TIMESTAMP);
statement ok
INSERT INTO t0(c1) VALUES ('2020-02-29 12:00:00'), ('1969-12-09 09:26:38'), ('2020-02-29 12:00:00');
statement ok
CREATE INDEX i0 ON t0(c1);
query I
SELECT c1 FROM t0 WHERE c1 <= '2007-07-07 07:07:07';
----
1969-12-09 09:26:38

View File

@@ -0,0 +1,51 @@
# name: test/sql/index/art/scan/test_art_scan_thresholds.test
# description: Test setting different index scan thresholds.
# group: [scan]
# Take the maximum of the absolute count and the percentage, which is 100%.
statement ok
SET index_scan_max_count = 1;
statement ok
SET index_scan_percentage = 1.0;
statement ok
CREATE TABLE integers(i INTEGER);
statement ok
INSERT INTO integers SELECT 42 FROM range(1000);
statement ok
INSERT INTO integers SELECT 43 FROM range(10000);
statement ok
CREATE INDEX idx ON integers(i);
query II
EXPLAIN ANALYZE SELECT i FROM integers WHERE i = 42;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
statement ok
SET index_scan_percentage = 0.000001;
# Use one as the maximum count, with the matching keys exceeding that maximum.
query II
EXPLAIN ANALYZE SELECT i FROM integers WHERE i = 42;
----
analyzed_plan <REGEX>:.*Type: Sequential Scan.*
# Let's also test more than STANDARD_VECTOR_SIZE values.
statement ok
SET index_scan_max_count = 4000;
statement ok
INSERT INTO integers SELECT 4242 FROM range(4000);
query II
EXPLAIN ANALYZE SELECT i FROM integers WHERE i = 4242;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*

View File

@@ -0,0 +1,44 @@
# name: test/sql/index/art/scan/test_hash_join_in_filter_index_scan.test
# description: Test using an index scan for IN filter pushdown via hash joins.
# group: [scan]
require tpch
statement ok
CALL dbgen(sf=0.01);
statement ok
CREATE TABLE random_orders AS (
(SELECT o_orderkey FROM orders
OFFSET 100
LIMIT 3)
UNION
(SELECT o_orderkey FROM orders
OFFSET (SELECT COUNT(*) FROM orders) / 2
LIMIT 3)
UNION
(SELECT o_orderkey FROM orders
OFFSET (SELECT COUNT(*) FROM orders) / 2 + 100000
LIMIT 3));
statement ok
CREATE TABLE orders_shuffled AS FROM orders ORDER BY random();
query II
EXPLAIN ANALYZE
SELECT o_orderkey FROM orders_shuffled WHERE o_orderkey IN (
SELECT UNNEST(LIST(o_orderkey)) FROM random_orders
) ORDER BY ALL;
----
analyzed_plan <REGEX>:.*Type: Sequential Scan.*
statement ok
ALTER TABLE orders_shuffled ADD PRIMARY KEY (o_orderkey);
query II
EXPLAIN ANALYZE
SELECT o_orderkey FROM orders_shuffled WHERE o_orderkey IN (
SELECT UNNEST(LIST(o_orderkey)) FROM random_orders
) ORDER BY ALL;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*

View File

@@ -0,0 +1,91 @@
# name: test/sql/index/art/scan/test_in_filter_index_scan.test
# description: Test using an index scan for IN filter pushdown.
# group: [scan]
statement ok
CREATE TABLE tbl AS SELECT range AS i FROM range(500000);
statement ok
ALTER TABLE tbl ADD PRIMARY KEY(i);
query II
EXPLAIN ANALYZE DELETE FROM tbl WHERE i IN (3, 50, 299, 123);
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT COUNT(*) FROM tbl;
----
499996
# Test with duplicate values.
query II
EXPLAIN ANALYZE SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101);
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) ORDER BY i;
----
2
42
100
101
# Test with different CONJUNCTION_AND removing values from the IN.
query II
EXPLAIN ANALYZE SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i != 42 AND i <= 100;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i != 42 AND i <= 100 ORDER BY i;
----
2
100
query II
EXPLAIN ANALYZE SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i = 42 AND i <= 100;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i = 42 AND i <= 100 ORDER BY i;
----
42
query II
EXPLAIN ANALYZE SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i < 101 AND i >= 42;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i < 101 AND i >= 42 ORDER BY i;
----
42
100
query II
EXPLAIN ANALYZE SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i > 42 AND i >= 42;
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i > 42 AND i >= 42 ORDER BY i;
----
100
101
# Test with multiple IN filters.
query II
EXPLAIN ANALYZE SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i > 42 AND i IN (56, 200, 2, 100);
----
analyzed_plan <REGEX>:.*Type: Index Scan.*
query I
SELECT i FROM tbl WHERE i IN (2, 42, 100, 42, 101) AND i > 42 AND i IN (56, 200, 2, 100) ORDER BY i;
----
100

View File

@@ -0,0 +1,67 @@
# name: test/sql/index/art/storage/test_art_auto_checkpoint.test
# description: Test auto checkpointing of the ART after CREATE and INSERT
# group: [storage]
# this test does not work with vsize = 2 because a low vector size changes the WAL threshold
require vector_size 2048
# test auto checkpointing after CREATE INDEX
load __TEST_DIR__/idx_checkpoint_create.db
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
PRAGMA wal_autocheckpoint='400KB';
# inserts approximately 786.0 KiB (256KB block size) or 338.0 KiB (16KB block size) of in-memory data,
# i.e., the WAL has to exceed that (barely)
statement ok
CREATE TABLE tbl AS SELECT range AS i FROM range(40000);
query I
SELECT used_blocks FROM pragma_database_size();
----
0
statement ok
CREATE INDEX idx ON tbl(i);
# ensure that we automatically checkpointed
query I
SELECT used_blocks > 0 FROM pragma_database_size();
----
1
# test auto checkpointing after INSERT
load __TEST_DIR__/idx_checkpoint_insert.db
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
PRAGMA wal_autocheckpoint='400KB';
# inserts just a few bytes (catalog entries), i.e., the WAL has to exceed that
statement ok
CREATE TABLE tbl (i INTEGER PRIMARY KEY);
query I
SELECT used_blocks FROM pragma_database_size();
----
0
statement ok
INSERT INTO tbl SELECT range FROM range(40000);
# ensure that we automatically checkpointed
query I
SELECT used_blocks > 0 FROM pragma_database_size();
----
1

View File

@@ -0,0 +1,50 @@
# name: test/sql/index/art/storage/test_art_checkpoint.test
# description: Test checkpointing an ART.
# group: [storage]
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE integers (i INTEGER PRIMARY KEY);
statement ok
INSERT INTO integers VALUES (1), (2), (3), (4), (5);
statement ok
CHECKPOINT;
restart
# Trigger a constraint violation.
statement error
INSERT INTO integers VALUES (1);
----
<REGEX>:Constraint Error.*violates primary key constraint.*
# Ensure partial blocks for serializing small ARTs.
statement ok
DROP TABLE integers;
statement ok
CREATE TABLE integers (i INTEGER);
statement ok
CREATE INDEX idx ON integers(i);
statement ok
CHECKPOINT;
# PREFIX, LEAF, NODE4, NODE256.
statement ok
INSERT INTO integers (SELECT range FROM range(512) UNION ALL SELECT 55);
statement ok
CHECKPOINT;
# We expect fewer than 4 additional blocks,
# because we combine partial blocks.
query I
SELECT total_blocks < 5 FROM pragma_database_size();
----
1

View File

@@ -0,0 +1,227 @@
# name: test/sql/index/art/storage/test_art_duckdb_versions.test
# description: Test compatibility of ART indexes for different duckdb versions
# group: [storage]
# data/storage/index_0-9-1.db was written with a 64-bit version of duckdb.
require 64bit
# The database is written with a vector size of 2048.
require vector_size 2048
# SQL to create index_0-9-1.db
# CREATE TABLE pk_tbl (id INTEGER PRIMARY KEY, name VARCHAR UNIQUE);
# CREATE TABLE idx_tbl (i INTEGER, j INTEGER, k INTEGER);
# CREATE TABLE fk_tbl (id INTEGER REFERENCES pk_tbl(id));
# INSERT INTO pk_tbl VALUES (1, 'alice'), (2, 'eve'), (3, 'hedy');
# INSERT INTO idx_tbl VALUES (10, 20, 30);
# INSERT INTO idx_tbl VALUES (11, 22, 31);
# INSERT INTO idx_tbl VALUES (110, 220, 310);
# INSERT INTO fk_tbl VALUES (2), (3);
# CREATE INDEX idx_1 ON idx_tbl(i, k);
# CREATE INDEX idx_2 ON idx_tbl (i);
load data/storage/index_0-9-1.db readonly
# ensure that we read the catalog correctly
query II
SELECT table_name, index_count FROM duckdb_tables() ORDER BY table_name;
----
fk_tbl 1
idx_tbl 2
pk_tbl 2
query II
SELECT index_name, table_name FROM duckdb_indexes() ORDER BY index_name;
----
idx_1 idx_tbl
idx_2 idx_tbl
query II
SELECT table_name, constraint_type FROM duckdb_constraints() ORDER BY ALL;
----
fk_tbl FOREIGN KEY
pk_tbl NOT NULL
pk_tbl PRIMARY KEY
pk_tbl UNIQUE
# ensure that we correctly load the data
query II
SELECT id, name FROM pk_tbl ORDER BY id;
----
1 alice
2 eve
3 hedy
# some index lookups
query I
SELECT id FROM pk_tbl WHERE id = 2;
----
2
query I
SELECT i FROM idx_tbl WHERE i = 11
----
11
# load the data into a new database to make it mutable
statement ok
EXPORT DATABASE '__TEST_DIR__/export_index_db' (FORMAT CSV)
load __TEST_DIR__/test_art_import.db
statement ok
IMPORT DATABASE '__TEST_DIR__/export_index_db'
# first, perform the same checks
query II
SELECT table_name, index_count FROM duckdb_tables() ORDER BY table_name;
----
fk_tbl 1
idx_tbl 2
pk_tbl 2
query II
SELECT index_name, table_name FROM duckdb_indexes() ORDER BY index_name;
----
idx_1 idx_tbl
idx_2 idx_tbl
query II
SELECT table_name, constraint_type FROM duckdb_constraints() ORDER BY ALL;
----
fk_tbl FOREIGN KEY
pk_tbl NOT NULL
pk_tbl PRIMARY KEY
pk_tbl UNIQUE
query II
SELECT id, name FROM pk_tbl ORDER BY id;
----
1 alice
2 eve
3 hedy
query I
SELECT id FROM pk_tbl WHERE id = 2;
----
2
query I
SELECT i FROM idx_tbl WHERE i = 11
----
11
# now try to break it
statement ok
INSERT INTO idx_tbl SELECT range, range, range FROM range(300000);
statement ok
CHECKPOINT;
query I
SELECT used_blocks > 2621440 / get_block_size('test_art_import') FROM pragma_database_size();
----
1
statement ok
CREATE INDEX ART_index ON idx_tbl(i);
statement error
CREATE INDEX idx_1 ON idx_tbl(i);
----
<REGEX>:Catalog Error.*Index with name "idx_1" already exists.*
# now try to use it again
query III
SELECT i, j, k FROM idx_tbl WHERE i = 110 ORDER BY ALL;
----
110 110 110
110 220 310
statement ok
CHECKPOINT
restart
query II
SELECT table_name, index_count FROM duckdb_tables() ORDER BY table_name;
----
fk_tbl 1
idx_tbl 3
pk_tbl 2
query II
SELECT index_name, table_name FROM duckdb_indexes() ORDER BY index_name;
----
ART_index idx_tbl
idx_1 idx_tbl
idx_2 idx_tbl
query II
SELECT table_name, constraint_type FROM duckdb_constraints() ORDER BY ALL;
----
fk_tbl FOREIGN KEY
pk_tbl NOT NULL
pk_tbl PRIMARY KEY
pk_tbl UNIQUE
query II
SELECT id, name FROM pk_tbl ORDER BY id;
----
1 alice
2 eve
3 hedy
query I
SELECT id FROM pk_tbl WHERE id = 2;
----
2
query I
SELECT i FROM idx_tbl WHERE i = 11
----
11
11
query III
SELECT i, j, k FROM idx_tbl WHERE i = 110 ORDER BY ALL;
----
110 110 110
110 220 310
statement ok
DROP INDEX idx_1;
statement ok
DROP INDEX idx_2;
statement ok
DROP INDEX ART_index;
statement ok
DROP TABLE fk_tbl;
statement ok
DROP TABLE idx_tbl;
statement ok
DROP TABLE pk_tbl;
statement ok
CHECKPOINT
query I
SELECT
CASE WHEN get_block_size('test_art_import') = 16384 THEN used_blocks < 3
ELSE used_blocks < 2 END
FROM pragma_database_size();
----
1

View File

@@ -0,0 +1,27 @@
# name: test/sql/index/art/storage/test_art_import.test
# description: Test index creation when importing the ART
# group: [storage]
statement ok
BEGIN TRANSACTION
statement ok
CREATE TABLE tracking("nflId" VARCHAR , "frameId" INTEGER, "gameId" INTEGER, "playId" INTEGER);
statement ok
INSERT INTO tracking values ('a', 0,0,0);
statement ok
CREATE INDEX nflid_idx ON tracking (nflid)
statement ok
CREATE UNIQUE INDEX tracking_key_idx ON tracking (gameId, playId, frameId, nflId)
statement ok
EXPORT DATABASE '__TEST_DIR__/index';
statement ok
ROLLBACK
statement ok
IMPORT DATABASE '__TEST_DIR__/index'

View File

@@ -0,0 +1,36 @@
# name: test/sql/index/art/storage/test_art_import_export.test
# description: Test the export and import of the ART
# group: [storage]
# Issue #4126
load __TEST_DIR__/test_art_export.db
statement ok
CREATE TABLE raw(
"year" SMALLINT,
"month" TINYINT,
"day" TINYINT,
"customer_ID" BIGINT
);
statement ok
INSERT INTO raw VALUES (1, 1, 1, 1);
statement ok
CREATE UNIQUE INDEX customer_year_month_idx ON raw (customer_ID, year, month);
restart
statement ok
EXPORT DATABASE '__TEST_DIR__/export_index_db' (FORMAT CSV)
load __TEST_DIR__/test_art_import.db
statement ok
IMPORT DATABASE '__TEST_DIR__/export_index_db'
statement error
INSERT INTO raw VALUES (1, 1, 1, 1);
----
Constraint Error: Duplicate key "customer_ID: 1, year: 1, month: 1" violates unique constraint

View File

@@ -0,0 +1,20 @@
# name: test/sql/index/art/storage/test_art_mem_limit.test
# description: Test retrieving memory information after creating an ART.
# group: [storage]
load __TEST_DIR__/index_mem_limit.db
statement ok
SET threads=1;
statement ok
SET memory_limit = '10MB';
statement ok
CREATE TABLE tbl AS SELECT range AS id FROM range(200000);
statement ok
CREATE INDEX idx ON tbl(id);
statement ok
FROM duckdb_memory();

View File

@@ -0,0 +1,214 @@
# name: test/sql/index/art/storage/test_art_names.test
# description: Test names ART indexes
# group: [storage]
load __TEST_DIR__/test_art_names.db
# Test PKs and UNIQUE constraints.
statement ok
CREATE TABLE tbl (i INTEGER PRIMARY KEY, j INTEGER UNIQUE);
# Test that index names match the internal constraints.
statement error
CREATE INDEX PRIMARY_tbl_0 ON tbl(i);
----
<REGEX>:Catalog Error.*An index with the name PRIMARY_tbl_0 already exists.*
statement error
CREATE INDEX UNIQUE_tbl_1 ON tbl(j);
----
<REGEX>:Catalog Error.*An index with the name UNIQUE_tbl_1 already exists.*
statement ok
INSERT INTO tbl SELECT range, range FROM range (3000);
statement error
INSERT INTO tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*violates unique constraint.*
statement error
INSERT INTO tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*violates primary key constraint.*
restart
# Test index name deserialization.
statement error
INSERT INTO tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*violates unique constraint.*
statement error
INSERT INTO tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*violates primary key constraint.*
statement error
CREATE INDEX PRIMARY_tbl_0 ON tbl(i);
----
<REGEX>:Catalog Error.*An index with the name PRIMARY_tbl_0 already exists.*
statement error
CREATE INDEX UNIQUE_tbl_1 ON tbl(j);
----
<REGEX>:Catalog Error.*An index with the name UNIQUE_tbl_1 already exists.*
statement error
INSERT INTO tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*violates primary key constraint.*
statement error
INSERT INTO tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*violates unique constraint.*
restart
statement ok
DROP TABLE tbl;
restart
# Test PKs, FKs, and UNIQUE constraints.
statement ok
CREATE TABLE tbl (i INTEGER PRIMARY KEY, j INTEGER UNIQUE);
statement ok
CREATE TABLE fk_tbl (i INTEGER, j INTEGER,
FOREIGN KEY (i) REFERENCES tbl(i),
FOREIGN KEY (j) REFERENCES tbl(j));
statement ok
INSERT INTO tbl SELECT range, range FROM range (3000);
statement ok
INSERT INTO fk_tbl SELECT range, range FROM range (3000);
# Check all constraint violations and catalog errors.
statement error
INSERT INTO tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*violates unique constraint.*
statement error
INSERT INTO tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*violates primary key constraint.*
statement error
INSERT INTO fk_tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*Violates foreign key constraint because key.*does not exist in the referenced table.*
statement error
INSERT INTO fk_tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*Violates foreign key constraint because key.*does not exist in the referenced table.*
statement error
CREATE INDEX PRIMARY_tbl_0 ON tbl(i);
----
<REGEX>:Catalog Error.*index with the name PRIMARY_tbl_0 already exists.*
statement error
CREATE INDEX UNIQUE_tbl_1 ON tbl(j);
----
<REGEX>:Catalog Error.*index with the name UNIQUE_tbl_1 already exists.*
# Fails on the FK table.
statement error
CREATE INDEX FOREIGN_fk_tbl_0 ON fk_tbl(i);
----
<REGEX>:Catalog Error.*index with the name FOREIGN_fk_tbl_0 already exists.*
statement error
CREATE INDEX FOREIGN_fk_tbl_1 ON fk_tbl(j);
----
<REGEX>:Catalog Error.*index with the name FOREIGN_fk_tbl_1 already exists.*
# Check all constraint violations and catalog errors.
statement error
INSERT INTO tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*violates unique constraint.*
statement error
INSERT INTO tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*violates primary key constraint.*
statement error
INSERT INTO fk_tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*Violates foreign key constraint because key.*does not exist in the referenced table.*
statement error
INSERT INTO fk_tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*Violates foreign key constraint because key.*does not exist in the referenced table.*
statement error
CREATE INDEX PRIMARY_tbl_0 ON tbl(i);
----
<REGEX>:Catalog Error.*index with the name PRIMARY_tbl_0 already exists.*
statement error
CREATE INDEX UNIQUE_tbl_1 ON tbl(j);
----
<REGEX>:Catalog Error.*index with the name UNIQUE_tbl_1 already exists.*
restart
statement error
CREATE INDEX PRIMARY_tbl_0 ON tbl(i);
----
<REGEX>:Catalog Error.*index with the name PRIMARY_tbl_0 already exists.*
statement error
CREATE INDEX UNIQUE_tbl_1 ON tbl(j);
----
<REGEX>:Catalog Error.*index with the name UNIQUE_tbl_1 already exists.*
# Fails on the FK table.
statement error
CREATE INDEX FOREIGN_fk_tbl_0 ON fk_tbl(i);
----
<REGEX>:Catalog Error.*index with the name FOREIGN_fk_tbl_0 already exists.*
statement error
CREATE INDEX FOREIGN_fk_tbl_1 ON fk_tbl(j);
----
<REGEX>:Catalog Error.*index with the name FOREIGN_fk_tbl_1 already exists.*
# Check all constraint errors.
statement error
INSERT INTO tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*Duplicate key "j: 20" violates unique constraint.*
statement error
INSERT INTO tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*Duplicate key "i: 20" violates primary key constraint.*
statement error
INSERT INTO fk_tbl VALUES (4000, 20);
----
<REGEX>:Constraint Error.*Violates foreign key constraint because key "i: 4000" does not exist in the referenced table.*
statement error
INSERT INTO fk_tbl VALUES (20, 4000);
----
<REGEX>:Constraint Error.*Violates foreign key constraint because key "j: 4000" does not exist in the referenced table.*

View File

@@ -0,0 +1,31 @@
# name: test/sql/index/art/storage/test_art_readonly.test
# description: Test that index creation is disabled in readonly mode
# group: [storage]
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE tbl (i INTEGER);
statement ok
CREATE INDEX idx_drop ON tbl(i);
# try index creation in readonly
load __TEST_DIR__/test_index.db readonly
statement error
CREATE INDEX idx ON tbl (i);
----
read-only mode
statement error
DROP INDEX idx_drop
----
read-only mode
# ensure that we did not create another index
query I
SELECT index_name FROM duckdb_indexes();
----
idx_drop

View File

@@ -0,0 +1,145 @@
# name: test/sql/index/art/storage/test_art_reclaim_storage.test_slow
# description: Test that the block manager reclaims index memory
# group: [storage]
load __TEST_DIR__/test_reclaim_space.db
statement ok
CREATE TABLE integers AS SELECT i FROM range(1000000) tbl(i);
statement ok
CHECKPOINT;
# save the block count and the used block count before index creation
statement ok
CREATE TABLE blocks_tbl AS SELECT total_blocks, used_blocks FROM pragma_database_size();
# index creation
statement ok
CREATE INDEX idx ON integers(i);
query I
SELECT i FROM integers WHERE i = 500000;
----
500000
statement ok
CHECKPOINT;
# save the total block count and the used block count after creating an index
statement ok
CREATE TABLE blocks_idx AS SELECT total_blocks, used_blocks FROM pragma_database_size();
# dropping the index
statement ok
DROP INDEX idx;
statement ok
CHECKPOINT;
# save the total block count after dropping the index
statement ok
CREATE TABLE blocks_drop_idx AS SELECT total_blocks, used_blocks FROM pragma_database_size();
statement ok
CREATE INDEX idx ON integers(i);
statement ok
CHECKPOINT;
query I
SELECT i FROM integers WHERE i = 500000;
----
500000
# now loop and always DROP INDEX, then recreate (reusing the same blocks)
loop i 0 4
statement ok
DROP INDEX idx;
statement ok
CHECKPOINT;
# we added another table, but dropping the index should get us back
# to more or less the block count that we had before creating the index
query I
SELECT current.total_blocks < blocks_drop_idx.total_blocks + 4
FROM pragma_database_size() AS current, blocks_drop_idx;
----
1
statement ok
CREATE INDEX idx ON integers(i);
statement ok
CHECKPOINT;
# we reclaim blocks, so we stay within some +4 blocks of our previous block count
query I
SELECT current.total_blocks < blocks_idx.total_blocks + 5
FROM pragma_database_size() current, blocks_idx;
----
1
query I
SELECT i FROM integers WHERE i = 500000;
----
500000
endloop
statement ok
CHECKPOINT;
statement ok
CREATE TABLE prev_delete_tbl AS SELECT total_blocks, used_blocks FROM pragma_database_size();
statement ok
DELETE FROM integers WHERE i > 100000;
statement ok
CHECKPOINT;
query I
SELECT current.used_blocks < prev_delete_tbl.total_blocks
FROM pragma_database_size() current, prev_delete_tbl;
----
1
statement ok
CHECKPOINT;
# now insert a bunch of values again
statement ok
INSERT INTO integers SELECT i FROM range(1000000) tbl(i);
# and make sure that we do not exceed/hit twice the original size
query I
SELECT current.total_blocks > blocks_idx.total_blocks
AND current.total_blocks < blocks_idx.total_blocks * 2
FROM pragma_database_size() current, blocks_idx;
----
1
statement ok
CHECKPOINT;
# now delete everything, but don't drop the index
statement ok
DELETE FROM integers;
statement ok
CHECKPOINT;
query I
SELECT current.used_blocks < blocks_idx.total_blocks
FROM pragma_database_size() current, blocks_idx;
----
1

View File

@@ -0,0 +1,100 @@
# name: test/sql/index/art/storage/test_art_reclaim_storage_pk_fk.test_slow
# description: Test that the block manager reclaims index memory of PK and FK tables
# group: [storage]
# PRIMARY KEY
load __TEST_DIR__/pk_mem_cleanup.db
query I
SELECT used_blocks < 2 FROM pragma_database_size();
----
1
statement ok
CREATE TABLE pk_tbl (i INTEGER PRIMARY KEY);
statement ok
INSERT INTO pk_tbl SELECT range FROM range(200000);
query I
SELECT used_blocks > 2 FROM pragma_database_size();
----
1
statement ok
DROP TABLE pk_tbl;
statement ok
CHECKPOINT
query I
SELECT used_blocks < 2 FROM pragma_database_size();
----
1
# FOREIGN KEY
load __TEST_DIR__/fk_mem_cleanup.db
query I
SELECT used_blocks < 2 FROM pragma_database_size();
----
1
statement ok
CREATE TABLE pk_tbl (i INTEGER PRIMARY KEY);
statement ok
INSERT INTO pk_tbl SELECT range FROM range(200000);
statement ok
CREATE TABLE fk_tbl (i INTEGER REFERENCES pk_tbl(i));
statement ok
INSERT INTO fk_tbl SELECT range FROM range(200000);
statement ok
DROP TABLE fk_tbl;
statement ok
DROP TABLE pk_tbl;
statement ok
CHECKPOINT
query I
SELECT used_blocks < 2 FROM pragma_database_size();
----
1
# UNIQUE
load __TEST_DIR__/unique_mem_cleanup.db
query I
SELECT used_blocks < 2 FROM pragma_database_size();
----
1
statement ok
CREATE TABLE unique_tbl (i INTEGER UNIQUE);
statement ok
INSERT INTO unique_tbl SELECT range FROM range(200000);
query I
SELECT used_blocks > 2 FROM pragma_database_size();
----
1
statement ok
DROP TABLE unique_tbl;
statement ok
CHECKPOINT
query I
SELECT used_blocks < 2 FROM pragma_database_size();
----
1

View File

@@ -0,0 +1,97 @@
# name: test/sql/index/art/storage/test_art_storage.test
# description: Test ART storage
# group: [storage]
load __TEST_DIR__/test_index.db
statement ok
CREATE TABLE integers(i integer,j integer)
statement ok
CREATE INDEX i_index ON integers(i)
# Insert values and create index
statement ok
INSERT INTO integers VALUES (1,1),(2,2),(3,3),(4,4),(5,5),
statement ok
checkpoint
restart
query I
SELECT j FROM integers where i = 3;
----
3
statement ok
DROP INDEX i_index
# test (de)serialization of leaves
statement ok
CREATE TABLE tbl_deser_scan(id INTEGER);
statement ok
INSERT INTO tbl_deser_scan SELECT range FROM range(100000);
statement ok
INSERT INTO tbl_deser_scan SELECT 424242 FROM range(5);
statement ok
INSERT INTO tbl_deser_scan SELECT 424243 FROM range(5);
statement ok
INSERT INTO tbl_deser_scan SELECT 1 FROM range(5);
statement ok
CREATE INDEX idx_deser_scan ON tbl_deser_scan(id);
restart
query I
SELECT id FROM tbl_deser_scan WHERE id >= 424242;
----
424242
424242
424242
424242
424242
424243
424243
424243
424243
424243
statement ok
CREATE TABLE max_row_id AS
SELECT max(rowid) AS id FROM tbl_deser_scan WHERE id = 424242;
restart
statement ok
DELETE FROM tbl_deser_scan WHERE rowid = (SELECT MAX(id) FROM max_row_id);
restart
statement ok
INSERT INTO tbl_deser_scan VALUES (1);
# ensure that we correctly (de)serialize parsed expressions of the index
statement ok
CREATE MACRO m(x, y := 7) AS x + y;
statement ok
CREATE TABLE tbl_m (x integer, y varchar);
statement ok
CREATE UNIQUE INDEX idx_m on tbl_m (m(tbl_m.x));
statement ok
insert into tbl_m VALUES (10, 'hello');
statement error
insert into tbl_m VALUES (10, 'world');
----
Constraint Error: Duplicate key "(x + 7): 17" violates unique constraint.

View File

@@ -0,0 +1,42 @@
# name: test/sql/index/art/storage/test_art_storage_long_prefixes.test
# description: Test ART storage with long prefixes
# group: [storage]
load __TEST_DIR__/test_art_load.db
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
SET wal_autocheckpoint = '10GB';
statement ok
CREATE TABLE history(id TEXT, type TEXT, PRIMARY KEY(id, type));
statement ok
INSERT INTO history(id, type) VALUES ('5_create_aaaaaaaaaaa_mapping', 'sql');
statement ok
CHECKPOINT
# Original issue #3019
load __TEST_DIR__/test_art_load_original.db
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
SET wal_autocheckpoint = '10GB';
statement ok
CREATE TABLE history(id TEXT, type TEXT, PRIMARY KEY(id, type));
statement ok
INSERT INTO history(id, type) VALUES ('m0001_initialize', 'sql');
statement ok
INSERT INTO history(id, type) VALUES ('m0005_create_aaaaaaaaaaa_mapping_table', 'sql');
statement ok
CHECKPOINT

View File

@@ -0,0 +1,24 @@
# name: test/sql/index/art/storage/test_art_storage_multi_checkpoint.test
# description: Test that serialized blocks are not corrupted in between checkpoints
# group: [storage]
load __TEST_DIR__/test_art_multi_checkpoint.db
statement ok
CREATE TABLE pk_integers(i INTEGER PRIMARY KEY)
statement ok
INSERT INTO pk_integers VALUES (1)
statement ok
CREATE TABLE pk_integers2(i INTEGER PRIMARY KEY)
statement ok
INSERT INTO pk_integers2 VALUES (1)
restart
query I
SELECT i FROM pk_integers WHERE i = 1;
----
1

View File

@@ -0,0 +1,60 @@
# name: test/sql/index/art/storage/test_art_wal_replay_drop_table.test
# description: Test replaying the WAL after creating an index in a transaction, and then dropping the table.
# group: [storage]
load __TEST_DIR__/art_wal_replay_drop_table.db
statement ok
SET threads=1;
statement ok
SET wal_autocheckpoint='1TB';
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
CREATE TABLE test (a INTEGER);
statement ok
INSERT INTO test SELECT range + 42 FROM range(100);
statement ok
CREATE TABLE alter_test (a INTEGER);
statement ok
INSERT INTO alter_test SELECT range + 42 FROM range(100);
# Let's also have an index outside the transaction.
statement ok
CREATE INDEX other_idx ON test(a);
statement ok
BEGIN TRANSACTION
# We add this to the UndoBuffer on commit.
statement ok
INSERT INTO test VALUES (0), (1);
statement ok
INSERT INTO alter_test VALUES (0), (1);
# We add this to the UndoBuffer immediately.
statement ok
CREATE UNIQUE INDEX i_index ON test(a);
statement ok
ALTER TABLE alter_test ADD PRIMARY KEY(a);
# Now drop the tables in the transaction.
statement ok
DROP TABLE test;
statement ok
DROP TABLE alter_test;
statement ok
COMMIT;
restart

Some files were not shown because too many files have changed in this diff Show More