Skip to content

Commit a7aa974

Browse files
committed
[paradedb] Just use the quickstart example as a test
No need to exhaustively verify or showcase different aspects of paradedb here.
1 parent 535795d commit a7aa974

1 file changed

Lines changed: 35 additions & 254 deletions

File tree

paradedb/tests/test_extension.py

Lines changed: 35 additions & 254 deletions
Original file line numberDiff line numberDiff line change
@@ -35,290 +35,71 @@ def test_connect_to_paradedb():
3535
conn.close()
3636

3737

38-
def test_create_table_and_insert():
39-
"""Test creating a table and inserting data."""
38+
def test_paradedb_quickstart():
39+
"""Test some of ParadeDB's quickstart examples."""
4040
conn = get_connection()
4141
cursor = conn.cursor()
4242

43-
table_name = f"test_table_{short_uid()}"
44-
45-
try:
46-
# Create table
47-
cursor.execute(f"""
48-
CREATE TABLE {table_name} (
49-
id SERIAL PRIMARY KEY,
50-
name TEXT NOT NULL,
51-
description TEXT
52-
);
53-
""")
54-
conn.commit()
55-
56-
# Insert data
57-
cursor.execute(f"""
58-
INSERT INTO {table_name} (name, description)
59-
VALUES ('Product A', 'A great product'),
60-
('Product B', 'Another product'),
61-
('Product C', 'Yet another product');
62-
""")
63-
conn.commit()
64-
65-
# Query data
66-
cursor.execute(f"SELECT * FROM {table_name} ORDER BY id;")
67-
results = cursor.fetchall()
68-
69-
assert len(results) == 3
70-
assert results[0][1] == "Product A"
71-
assert results[1][1] == "Product B"
72-
assert results[2][1] == "Product C"
73-
74-
finally:
75-
# Cleanup
76-
cursor.execute(f"DROP TABLE IF EXISTS {table_name};")
77-
conn.commit()
78-
cursor.close()
79-
conn.close()
80-
81-
82-
def test_paradedb_pg_search_extension():
83-
"""Test ParadeDB's pg_search extension for full-text search using v2 API."""
84-
conn = get_connection()
85-
cursor = conn.cursor()
86-
87-
table_name = f"products_{short_uid()}"
43+
table_name = f"mock_items_{short_uid()}"
8844
index_name = f"{table_name}_idx"
8945

9046
try:
91-
# Create table
47+
# Load sample data
9248
cursor.execute(f"""
93-
CREATE TABLE {table_name} (
94-
id SERIAL PRIMARY KEY,
95-
name TEXT NOT NULL,
96-
description TEXT
49+
CALL paradedb.create_bm25_test_table(
50+
schema_name => 'public',
51+
table_name => '{table_name}'
9752
);
9853
""")
99-
conn.commit()
100-
101-
# Insert sample data
102-
cursor.execute(f"""
103-
INSERT INTO {table_name} (name, description) VALUES
104-
('Laptop', 'High performance laptop with 16GB RAM and SSD storage'),
105-
('Smartphone', 'Latest smartphone with advanced camera features'),
106-
('Headphones', 'Wireless noise-canceling headphones for music lovers'),
107-
('Tablet', 'Portable tablet with retina display'),
108-
('Smartwatch', 'Fitness tracking smartwatch with heart rate monitor');
109-
""")
110-
conn.commit()
11154

112-
# Create BM25 search index using ParadeDB v2 API (CREATE INDEX syntax)
55+
# Create search index
11356
cursor.execute(f"""
114-
CREATE INDEX {index_name} ON {table_name}
115-
USING bm25 (id, name, description)
57+
CREATE INDEX search_idx ON {table_name}
58+
USING bm25 (id, description, category, rating, in_stock, created_at, metadata, weight_range)
11659
WITH (key_field='id');
11760
""")
118-
conn.commit()
119-
120-
# Search for products containing 'wireless' using ||| operator (disjunction/OR)
121-
cursor.execute(f"""
122-
SELECT id, name, description
123-
FROM {table_name}
124-
WHERE description ||| 'wireless';
125-
""")
126-
results = cursor.fetchall()
127-
128-
assert len(results) >= 1
129-
assert any("Headphones" in row[1] for row in results)
13061

131-
# Search for products containing 'laptop' in name or description
13262
cursor.execute(f"""
133-
SELECT id, name, description
134-
FROM {table_name}
135-
WHERE name ||| 'laptop' OR description ||| 'laptop';
63+
SELECT description, rating, category
64+
FROM {table_name}
65+
LIMIT 3;
13666
""")
13767
results = cursor.fetchall()
68+
assert results == [
69+
("Ergonomic metal keyboard", 4, "Electronics"),
70+
("Plastic Keyboard", 4, "Electronics"),
71+
("Sleek running shoes", 5, "Footwear"),
72+
]
13873

139-
assert len(results) >= 1
140-
assert any("Laptop" in row[1] for row in results)
141-
142-
finally:
143-
# Cleanup - drop index first, then table
144-
cursor.execute(f"DROP INDEX IF EXISTS {index_name};")
145-
cursor.execute(f"DROP TABLE IF EXISTS {table_name};")
146-
conn.commit()
147-
cursor.close()
148-
conn.close()
149-
150-
151-
def test_paradedb_search_with_scoring():
152-
"""Test ParadeDB's BM25 search with relevance scoring."""
153-
conn = get_connection()
154-
cursor = conn.cursor()
155-
156-
table_name = f"docs_{short_uid()}"
157-
index_name = f"{table_name}_idx"
158-
159-
try:
160-
# Create table with text content
161-
cursor.execute(f"""
162-
CREATE TABLE {table_name} (
163-
id SERIAL PRIMARY KEY,
164-
title TEXT NOT NULL,
165-
content TEXT
166-
);
167-
""")
168-
conn.commit()
169-
170-
# Insert sample documents
171-
cursor.execute(f"""
172-
INSERT INTO {table_name} (title, content) VALUES
173-
('Introduction to Python', 'Python is a versatile programming language used for web development, data science, and automation.'),
174-
('JavaScript Basics', 'JavaScript is essential for front-end web development and can also be used on the server side with Node.js.'),
175-
('Database Design', 'Good database design is crucial for application performance and data integrity.'),
176-
('Machine Learning 101', 'Machine learning enables computers to learn from data without explicit programming.'),
177-
('Cloud Computing', 'Cloud computing provides on-demand access to computing resources over the internet.');
178-
""")
179-
conn.commit()
180-
181-
# Create search index using v2 API
182-
cursor.execute(f"""
183-
CREATE INDEX {index_name} ON {table_name}
184-
USING bm25 (id, title, content)
185-
WITH (key_field='id');
186-
""")
187-
conn.commit()
188-
189-
# Search for programming-related documents with scoring
74+
# Match conjunction
19075
cursor.execute(f"""
191-
SELECT id, title, pdb.score(id) as score
76+
SELECT description, rating, category
19277
FROM {table_name}
193-
WHERE content ||| 'programming'
194-
ORDER BY score DESC;
78+
WHERE description &&& 'running shoes' AND rating > 2
79+
ORDER BY rating
80+
LIMIT 5;
19581
""")
19682
results = cursor.fetchall()
83+
assert results == [("Sleek running shoes", 5, "Footwear")]
19784

198-
assert len(results) >= 1
199-
# Python and Machine Learning docs should match
200-
titles = [row[1] for row in results]
201-
assert any("Python" in t or "Machine Learning" in t for t in titles)
202-
203-
finally:
204-
# Cleanup
205-
cursor.execute(f"DROP INDEX IF EXISTS {index_name};")
206-
cursor.execute(f"DROP TABLE IF EXISTS {table_name};")
207-
conn.commit()
208-
cursor.close()
209-
conn.close()
210-
211-
212-
def test_paradedb_conjunction_search():
213-
"""Test ParadeDB's conjunction (AND) search using &&& operator."""
214-
conn = get_connection()
215-
cursor = conn.cursor()
216-
217-
table_name = f"items_{short_uid()}"
218-
index_name = f"{table_name}_idx"
219-
220-
try:
221-
# Create table
222-
cursor.execute(f"""
223-
CREATE TABLE {table_name} (
224-
id SERIAL PRIMARY KEY,
225-
name TEXT NOT NULL,
226-
description TEXT
227-
);
228-
""")
229-
conn.commit()
230-
231-
# Insert sample data
232-
cursor.execute(f"""
233-
INSERT INTO {table_name} (name, description) VALUES
234-
('Running Shoes', 'Lightweight running shoes for marathon training'),
235-
('Walking Shoes', 'Comfortable walking shoes for daily use'),
236-
('Running Gear', 'Essential gear for running enthusiasts'),
237-
('Basketball Shoes', 'High-top basketball shoes with ankle support');
238-
""")
239-
conn.commit()
240-
241-
# Create BM25 index
242-
cursor.execute(f"""
243-
CREATE INDEX {index_name} ON {table_name}
244-
USING bm25 (id, name, description)
245-
WITH (key_field='id');
246-
""")
247-
conn.commit()
248-
249-
# Search using conjunction (AND) - must contain both 'running' AND 'shoes'
85+
# BM25 scoring
25086
cursor.execute(f"""
251-
SELECT id, name, description
87+
SELECT description, pdb.score(id)
25288
FROM {table_name}
253-
WHERE name &&& 'running shoes';
89+
WHERE description ||| 'running shoes' AND rating > 2
90+
ORDER BY score DESC
91+
LIMIT 5;
25492
""")
25593
results = cursor.fetchall()
256-
257-
assert len(results) >= 1
258-
# Should match "Running Shoes" but not "Running Gear" or "Walking Shoes"
259-
assert any("Running Shoes" in row[1] for row in results)
260-
94+
assert results == [
95+
("Sleek running shoes", 6.817111),
96+
("Generic shoes", 3.8772602),
97+
("White jogging shoes", 3.4849067),
98+
]
26199
finally:
262-
# Cleanup
100+
# Cleanup - drop index first, then table
263101
cursor.execute(f"DROP INDEX IF EXISTS {index_name};")
264102
cursor.execute(f"DROP TABLE IF EXISTS {table_name};")
265103
conn.commit()
266104
cursor.close()
267105
conn.close()
268-
269-
270-
def test_standard_postgres_features():
271-
"""Test that standard PostgreSQL features work correctly."""
272-
conn = get_connection()
273-
cursor = conn.cursor()
274-
275-
table_name = f"users_{short_uid()}"
276-
277-
try:
278-
# Create table with various PostgreSQL types
279-
cursor.execute(f"""
280-
CREATE TABLE {table_name} (
281-
id SERIAL PRIMARY KEY,
282-
name VARCHAR(100) NOT NULL,
283-
email VARCHAR(255) UNIQUE,
284-
metadata JSONB,
285-
tags TEXT[],
286-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
287-
);
288-
""")
289-
conn.commit()
290-
291-
# Insert data with JSONB and arrays
292-
cursor.execute(f"""
293-
INSERT INTO {table_name} (name, email, metadata, tags)
294-
VALUES
295-
('Alice', 'alice@example.com', '{{"role": "admin", "level": 5}}', ARRAY['active', 'premium']),
296-
('Bob', 'bob@example.com', '{{"role": "user", "level": 2}}', ARRAY['active']),
297-
('Charlie', 'charlie@example.com', '{{"role": "user", "level": 3}}', ARRAY['inactive']);
298-
""")
299-
conn.commit()
300-
301-
# Query with JSONB operators
302-
cursor.execute(f"""
303-
SELECT name FROM {table_name}
304-
WHERE metadata->>'role' = 'admin';
305-
""")
306-
results = cursor.fetchall()
307-
assert len(results) == 1
308-
assert results[0][0] == "Alice"
309-
310-
# Query with array operators
311-
cursor.execute(f"""
312-
SELECT name FROM {table_name}
313-
WHERE 'premium' = ANY(tags);
314-
""")
315-
results = cursor.fetchall()
316-
assert len(results) == 1
317-
assert results[0][0] == "Alice"
318-
319-
finally:
320-
# Cleanup
321-
cursor.execute(f"DROP TABLE IF EXISTS {table_name};")
322-
conn.commit()
323-
cursor.close()
324-
conn.close()

0 commit comments

Comments
 (0)