[[server]] name = "Primary" [server.style.Automatic] [server.setup] sql = """ DROP TABLE IF EXISTS test CASCADE; DROP TABLE IF EXISTS categories CASCADE; CREATE EXTENSION IF NOT EXISTS pg_search CASCADE; CREATE TABLE categories ( id INTEGER PRIMARY KEY, name TEXT NOT NULL ); CREATE TABLE test ( id SERIAL8 NOT NULL PRIMARY KEY, message TEXT, category TEXT DEFAULT 'common', category_id INTEGER NOT NULL, payload TEXT ); INSERT INTO categories (id, name) SELECT i, 'category ' || i::text FROM generate_series(1, 100) AS s(i); INSERT INTO test (message, category, category_id, payload) SELECT (ARRAY['beer wine cheese', 'beer wine', 'beer cheese', 'beer', 'wine cheese', 'wine', 'cheese', 'bread butter'])[1 + (i % 8)] || ' ' || i::text, CASE WHEN i % 10 = 0 THEN 'rare' ELSE 'common' END, 1 + (i % 100), 'payload ' || i::text FROM generate_series(1, 10000) AS s(i); CREATE INDEX idxtest ON test USING paradedb ( id, message, category_id, (category::pdb.literal) ) WITH ( numeric_fields = '{"category_id": {"fast": true}}' ); CREATE INDEX idxcategories ON categories USING paradedb (id, name) WITH ( text_fields = '{"name": {"fast": true, "tokenizer": {"type": "raw"}}}' ); -- Populate the visibility map before workers assert the index-only scan plan. -- A concurrent vacuum job or autovacuum may not finish before that assertion. VACUUM (ANALYZE) test; ANALYZE categories; CREATE OR REPLACE FUNCTION assert(a bigint, b bigint) RETURNS bool LANGUAGE plpgsql AS $$ DECLARE current_txid bigint; BEGIN current_txid := txid_current(); IF a <> b THEN RAISE EXCEPTION 'Assertion failed: % <> %. Transaction ID: %', a, b, current_txid; END IF; RETURN true; END; $$; ALTER SYSTEM SET autovacuum_naptime = '1s'; SELECT pg_reload_conf(); """ [server.teardown] sql = """ DROP TABLE test CASCADE; DROP TABLE categories CASCADE; DROP EXTENSION pg_search CASCADE; """ [server.monitor] refresh_ms = 10 title = "Monitor Index Size" log_columns = ["block_count", "segment_count"] sql = """ SELECT pg_relation_size('idxtest') / current_setting('block_size')::int AS block_count, ( SELECT COUNT(*)::bigint FROM paradedb.index_info('idxtest') ) AS segment_count """ [[jobs]] refresh_ms = 100 title = "Postgres Index Only Scan Fallback" log_tps = true on_connect = """ SET max_parallel_workers = 0; SET paradedb.enable_custom_scan = off; SET enable_indexscan = off; SET enable_seqscan = off; SET enable_bitmapscan = off; """ sql_plan_contains = "Index Only Scan" sql = """ SELECT id FROM test WHERE message ||| 'cheese' LIMIT 100; """ [[jobs]] refresh_ms = 5 title = "Postgres Index Scan Fallback" log_tps = true on_connect = """ SET max_parallel_workers = 0; SET paradedb.enable_custom_scan = off; SET enable_seqscan = off; """ sql_plan_contains = "Index Scan" sql = """ SELECT id, message, payload FROM test WHERE message ||| 'cheese' LIMIT 100; """ [[jobs]] refresh_ms = 5 title = "Unordered Top K Base Scan" log_tps = true on_connect = """ SET max_parallel_workers_per_gather = 0; """ sql_plan_contains = "TopKScanExecState" sql = """ SELECT id, message, payload FROM test WHERE message ||| 'wine' LIMIT 100; """ [[jobs]] refresh_ms = 5 title = "Normal Base Scan" log_tps = true on_connect = """ SET max_parallel_workers_per_gather = 0; """ sql_plan_contains = "NormalScanExecState" sql = """ SELECT id, message, payload FROM test WHERE message &&& 'beer wine'; """ [[jobs]] refresh_ms = 5 title = "Columnar Base Scan" log_tps = true on_connect = """ SET paradedb.enable_columnar_exec = on; """ sql_plan_contains = "ColumnarExecState" sql = """ SELECT id, category FROM test WHERE message ||| 'beer' AND category === 'rare'; """ [[jobs]] refresh_ms = 5 title = "Aggregate Scan" log_tps = true sql_plan_contains = "ParadeDB Aggregate Scan" sql = """ SELECT assert((pdb.agg('{"value_count": {"field": "id"}}'::jsonb)->>'value')::numeric::bigint, 5000::bigint) FROM test WHERE message ||| 'beer'; """ [[jobs]] refresh_ms = 5 title = "Grouped Aggregate Scan" log_tps = true sql_plan_contains = "ParadeDB Aggregate Scan" sql = """ SELECT category_id, count(*) FROM test WHERE message ||| 'beer' GROUP BY category_id; """ [[jobs]] refresh_ms = 5 title = "Score-ordered Top K Base Scan" log_tps = true sql_plan_contains = "TopKScanExecState" sql = """ SELECT id FROM test WHERE message ||| 'beer' ORDER BY paradedb.score(id) DESC LIMIT 10; """ [[jobs]] refresh_ms = 5 title = "JoinScan" log_tps = true on_connect = """ SET paradedb.enable_join_custom_scan = on; """ sql_plan_contains = "ParadeDB Join Scan" sql = """ SELECT t.id, t.message, c.name FROM test t JOIN categories c ON t.category_id = c.id WHERE t.message ||| 'beer' ORDER BY t.id LIMIT 25; """ [[jobs]] refresh_ms = 25 title = "Update random values" log_tps = true sql = """ UPDATE test SET message = substring(message FROM 1 FOR length(message)-1) || chr((trunc(random() * 26) + 65)::int) WHERE id < 10; """ [[jobs]] refresh_ms = 25 title = "Rotate join keys" log_tps = true sql = """ UPDATE test SET category_id = (category_id % 100) + 1 WHERE id BETWEEN 1 AND 100; """ [[jobs]] refresh_ms = 25 title = "Update joined rows" log_tps = true sql = """ UPDATE categories SET name = 'category ' || id::text || ' ' || txid_current()::text WHERE id <= 10; """ [[jobs]] refresh_ms = 10 title = "Insert value A" log_tps = true sql = """ INSERT INTO test (message, category_id, payload) VALUES ('test A', 1, 'inserted'); """ [[jobs]] refresh_ms = 10 title = "Insert value B" log_tps = true sql = """ INSERT INTO test (message, category_id, payload) VALUES ('test B', 2, 'inserted'); """ [[jobs]] refresh_ms = 10 title = "Delete values" sql = """ DELETE FROM test WHERE id > 10000; """ [[jobs]] refresh_ms = 3000 title = "Vacuum" log_tps = true sql = """ SET vacuum_freeze_min_age = 0; VACUUM test; """