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,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

View File

@@ -0,0 +1,92 @@
# name: test/sql/index/art/storage/test_art_wal_replay_in_tx.test
# description: Test replaying the WAL after creating an index in a transaction.
# group: [storage]
load __TEST_DIR__/art_wal_replay_tx.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);
statement ok
CREATE TABLE drop_test (a INTEGER);
statement ok
INSERT INTO drop_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);
statement ok
INSERT INTO drop_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);
statement ok
CREATE INDEX drop_idx ON drop_test(a);
statement ok
DROP INDEX drop_idx;
statement ok
DELETE FROM test WHERE a = 1;
statement ok
DELETE FROM alter_test WHERE a = 1;
statement ok
COMMIT;
restart
statement error
INSERT INTO test VALUES (0);
----
<REGEX>:Constraint Error.*violates unique constraint.*
statement error
INSERT INTO alter_test VALUES (0);
----
<REGEX>:Constraint Error.*violates primary key constraint.*
statement ok
INSERT INTO test VALUES (1);
statement ok
INSERT INTO alter_test VALUES (1);
statement ok
CREATE INDEX drop_idx ON test(a);

View File

@@ -0,0 +1,36 @@
# name: test/sql/index/art/storage/test_art_wal_replay_with_buffer.test
# description: Test replaying the WAL and buffering outstanding appends.
# group: [storage]
load __TEST_DIR__/test_art_wal_buffer.db
statement ok
SET wal_autocheckpoint = '1TB';
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
CREATE TABLE tbl (u_2 UNION("string" VARCHAR, "bool" BOOLEAN))
statement ok
CREATE UNIQUE INDEX idx_u_2_1 ON tbl ((u_2.string));
statement ok
INSERT INTO tbl VALUES ('helloo');
restart
statement ok
INSERT INTO tbl VALUES ('hellooo');
statement ok
CHECKPOINT;
restart
query I
SELECT * FROM tbl ORDER BY ALL;
----
helloo
hellooo

View File

@@ -0,0 +1,61 @@
# name: test/sql/index/art/storage/test_art_wal_replay_with_buffer_concurrent.test
# description: Test replaying the WAL and buffering outstanding appends in a concurrent loop.
# group: [storage]
load __TEST_DIR__/test_art_wal_buffer_concurrent.db
statement ok
SET wal_autocheckpoint = '1TB';
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
CREATE TABLE tbl (u_2 UNION("string" VARCHAR, "bool" BOOLEAN))
statement ok
CREATE UNIQUE INDEX idx_1 ON tbl ((u_2.string));
statement ok
CREATE UNIQUE INDEX idx_2 ON tbl ((u_2.string));
statement ok
CREATE UNIQUE INDEX idx_3 ON tbl ((u_2.string));
statement ok
CREATE UNIQUE INDEX idx_4 ON tbl ((u_2.string));
statement ok
CREATE UNIQUE INDEX idx_5 ON tbl ((u_2.string));
statement ok
INSERT INTO tbl VALUES ('helloo');
restart
concurrentloop threadid 0 10
statement ok
INSERT INTO tbl VALUES ('hellooo_${threadid}');
endloop
statement ok
CHECKPOINT;
restart
query I
SELECT * FROM tbl ORDER BY ALL;
----
helloo
hellooo_0
hellooo_1
hellooo_2
hellooo_3
hellooo_4
hellooo_5
hellooo_6
hellooo_7
hellooo_8
hellooo_9

View File

@@ -0,0 +1,97 @@
# name: test/sql/index/art/storage/test_upsert_reclaim_space.test_slow
# description: Test that the block manager reclaims index memory after UPSERT.
# group: [storage]
load __TEST_DIR__/test_reclaim_upsert_space.db
statement ok
CREATE TABLE tbl AS SELECT i FROM range(10000) tbl(i);
statement ok
CHECKPOINT;
# Block count and used block count before index creation.
statement ok
CREATE TABLE blocks_tbl AS SELECT total_blocks, used_blocks FROM pragma_database_size();
statement ok
CREATE UNIQUE INDEX idx ON tbl(i);
query I
SELECT i FROM tbl WHERE i = 5000;
----
5000
statement ok
CHECKPOINT;
# Block count and used block count after index creation.
statement ok
CREATE TABLE blocks_idx AS SELECT total_blocks, used_blocks FROM pragma_database_size();
statement ok
DELETE FROM tbl;
statement ok
CHECKPOINT;
# Block count and used block count after deleting from the table.
statement ok
CREATE TABLE blocks_del_tbl AS SELECT total_blocks, used_blocks FROM pragma_database_size();
statement ok
INSERT INTO tbl SELECT i FROM range(10000) tbl(i);
statement ok
CHECKPOINT;
# Loop while DELETE + INSERT in tx.
loop i 0 10
statement ok con1
BEGIN;
statement ok con1
DELETE FROM tbl;
# We should not have significantly move blocks than in previous iterations.
query I
SELECT current.total_blocks < blocks_del_tbl.total_blocks + 6
FROM pragma_database_size() AS current, blocks_del_tbl;
----
1
statement ok con1
INSERT INTO tbl SELECT i FROM range(10000) tbl(i);
statement ok con1
COMMIT;
statement ok con1
CHECKPOINT;
# We should not have significantly move blocks than in previous iterations.
query I
SELECT current.total_blocks < blocks_idx.total_blocks + 6
FROM pragma_database_size() AS current, blocks_idx;
----
1
endloop
statement ok
DROP INDEX idx;
# Same block count as before the index creation.
query I
SELECT current.total_blocks < blocks_tbl.total_blocks + 4
FROM pragma_database_size() AS current, blocks_tbl;
----
1