Skip to content

Commit

Permalink
Fix bug where SQL query in version match check would execute outside …
Browse files Browse the repository at this point in the history
…of an outer snapshot or portal (#266)
  • Loading branch information
therealdarkknight authored Jan 23, 2024
1 parent 37a587d commit 7b66765
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/hnsw/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ float4 *ToFloat4Array(ArrayType *arr)
// This is used to prevent interacting with the index when the two don't match
bool VersionsMatch()
{
// If a parallel worker runs as a result of query execution, executing the SQL query below will lead to the
// error "ERROR: cannot execute SQL without an outer snapshot or portal." Instead of loading in a snapshot, we
// simply return if one doesn't exist, the idea being that in the case of a parallel worker running this
// function, the original worker will have already run this function (after which all the parallel workers run
// this function, invoked by _PG_init). We return true so that we suppress any version mismatch messages from
// callers of this function
if(!ActiveSnapshotSet()) {
version_checked = versions_match = false;
return true;
}

if(likely(version_checked)) {
return versions_match;
} else {
Expand Down
36 changes: 36 additions & 0 deletions test/expected/missing_outer_snapshot_portal.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-- This test is to check that Lantern properly handles missing outer snapshots or portals when it is loaded
-- So far, this test checks that Lantern handles cases of initializing parallel workers properly.
-- Specifically, we test that Lantern performs the version match check by only performing its initialization SQL queries when a proper outer snapshot or portal exists.
-- This is to prevent the following error: "ERROR: cannot execute SQL without an outer snapshot or portal"
-- Note: Dropping and loading the extension again is necessary to test the desired missing outer snapshot/portal behavior
DROP EXTENSION lantern;
CREATE EXTENSION lantern;
CREATE TABLE IF NOT EXISTS ourtable (
id SERIAL,
v REAL[128]
);
\copy ourtable (v) FROM '/tmp/lantern/vector_datasets/siftsmall_base_arrays.csv' with csv;
SET max_parallel_workers_per_gather TO 4;
SET max_parallel_workers TO 8;
--- Make parallel plans more favorable ---
SET min_parallel_table_scan_size TO '8kB';
SET parallel_setup_cost TO 10;
SET parallel_tuple_cost TO 0.001;
SET seq_page_cost TO 10;
-- This query should have a parallel plan
EXPLAIN (COSTS false) SELECT COUNT(*) FROM ourtable;
QUERY PLAN
-------------------------------------------------
Finalize Aggregate
-> Gather
Workers Planned: 4
-> Partial Aggregate
-> Parallel Seq Scan on ourtable
(5 rows)

SELECT COUNT(*) FROM ourtable;
count
-------
10000
(1 row)

2 changes: 1 addition & 1 deletion test/schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
# - every test that needs to be run iff pgvector is installed appears in a 'test_pgvector:' line
# - 'test' lines may have multiple space-separated tests. All tests in a single 'test' line will be run in parallel

test: hnsw_config hnsw_correct hnsw_create hnsw_create_expr hnsw_dist_func hnsw_insert hnsw_select hnsw_todo hnsw_index_from_file hnsw_cost_estimate ext_relocation hnsw_ef_search hnsw_failure_point hnsw_operators hnsw_blockmap_create hnsw_create_unlogged hnsw_insert_unlogged hnsw_logged_unlogged
test: hnsw_config hnsw_correct hnsw_create hnsw_create_expr hnsw_dist_func hnsw_insert hnsw_select hnsw_todo hnsw_index_from_file hnsw_cost_estimate ext_relocation hnsw_ef_search hnsw_failure_point hnsw_operators hnsw_blockmap_create hnsw_create_unlogged hnsw_insert_unlogged hnsw_logged_unlogged missing_outer_snapshot_portal
test_pgvector: hnsw_vector
test_extras: hnsw_extras
33 changes: 33 additions & 0 deletions test/sql/missing_outer_snapshot_portal.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- This test is to check that Lantern properly handles missing outer snapshots or portals when it is loaded

-- So far, this test checks that Lantern handles cases of initializing parallel workers properly.
-- Specifically, we test that Lantern performs the version match check by only performing its initialization SQL queries when a proper outer snapshot or portal exists.
-- This is to prevent the following error: "ERROR: cannot execute SQL without an outer snapshot or portal"

-- Note: Dropping and loading the extension again is necessary to test the desired missing outer snapshot/portal behavior
DROP EXTENSION lantern;
CREATE EXTENSION lantern;

CREATE TABLE IF NOT EXISTS ourtable (
id SERIAL,
v REAL[128]
);

\copy ourtable (v) FROM '/tmp/lantern/vector_datasets/siftsmall_base_arrays.csv' with csv;

SET max_parallel_workers_per_gather TO 4;
SET max_parallel_workers TO 8;

--- Make parallel plans more favorable ---
SET min_parallel_table_scan_size TO '8kB';

SET parallel_setup_cost TO 10;
SET parallel_tuple_cost TO 0.001;

SET seq_page_cost TO 10;

-- This query should have a parallel plan
EXPLAIN (COSTS false) SELECT COUNT(*) FROM ourtable;
SELECT COUNT(*) FROM ourtable;


0 comments on commit 7b66765

Please sign in to comment.