From 4a1d5c1d419212a5960cd85e7f36b4d2e1828733 Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 16 Apr 2026 08:41:15 -0400 Subject: [PATCH 1/2] feat(cold-sql): add topic1/topic2/topic3 indexes for log filtering Only topic0 was indexed previously. Most ERC-20/721 Transfer event lookups filter on topic1 (from address) or topic2 (to address), causing sequential scans on the logs table. Adds migration 002 with indexes on all three remaining topic columns. Uses CREATE INDEX IF NOT EXISTS for idempotent application. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../cold-sql/migrations/002_add_topic_indexes.sql | 9 +++++++++ .../migrations/002_add_topic_indexes_pg.sql | 9 +++++++++ crates/cold-sql/src/backend.rs | 13 ++++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 crates/cold-sql/migrations/002_add_topic_indexes.sql create mode 100644 crates/cold-sql/migrations/002_add_topic_indexes_pg.sql diff --git a/crates/cold-sql/migrations/002_add_topic_indexes.sql b/crates/cold-sql/migrations/002_add_topic_indexes.sql new file mode 100644 index 0000000..2ddcce8 --- /dev/null +++ b/crates/cold-sql/migrations/002_add_topic_indexes.sql @@ -0,0 +1,9 @@ +-- Add indexes on topic1, topic2, topic3 for log filtering. +-- +-- topic0 already has an index (001_initial.sql). Most ERC-20/721 +-- Transfer lookups filter on topic1 (from) or topic2 (to), which +-- previously required sequential scans. + +CREATE INDEX IF NOT EXISTS idx_logs_topic1 ON logs (topic1); +CREATE INDEX IF NOT EXISTS idx_logs_topic2 ON logs (topic2); +CREATE INDEX IF NOT EXISTS idx_logs_topic3 ON logs (topic3); diff --git a/crates/cold-sql/migrations/002_add_topic_indexes_pg.sql b/crates/cold-sql/migrations/002_add_topic_indexes_pg.sql new file mode 100644 index 0000000..c42ee78 --- /dev/null +++ b/crates/cold-sql/migrations/002_add_topic_indexes_pg.sql @@ -0,0 +1,9 @@ +-- Add indexes on topic1, topic2, topic3 for log filtering. +-- +-- topic0 already has an index (001_initial_pg.sql). Most ERC-20/721 +-- Transfer lookups filter on topic1 (from) or topic2 (to), which +-- previously required sequential scans. + +CREATE INDEX IF NOT EXISTS idx_logs_topic1 ON logs (topic1); +CREATE INDEX IF NOT EXISTS idx_logs_topic2 ON logs (topic2); +CREATE INDEX IF NOT EXISTS idx_logs_topic3 ON logs (topic3); diff --git a/crates/cold-sql/src/backend.rs b/crates/cold-sql/src/backend.rs index 3065cd9..93c757b 100644 --- a/crates/cold-sql/src/backend.rs +++ b/crates/cold-sql/src/backend.rs @@ -115,9 +115,15 @@ impl SqlColdBackend { let backend = conn.backend_name().to_owned(); drop(conn); - let migration = match backend.as_str() { - "PostgreSQL" => include_str!("../migrations/001_initial_pg.sql"), - "SQLite" => include_str!("../migrations/001_initial.sql"), + let (migration, migration_002) = match backend.as_str() { + "PostgreSQL" => ( + include_str!("../migrations/001_initial_pg.sql"), + include_str!("../migrations/002_add_topic_indexes_pg.sql"), + ), + "SQLite" => ( + include_str!("../migrations/001_initial.sql"), + include_str!("../migrations/002_add_topic_indexes.sql"), + ), other => { return Err(SqlColdError::Convert(format!( "unsupported database backend: {other}" @@ -128,6 +134,7 @@ impl SqlColdBackend { // connection that subsequent queries will use. let is_postgres = backend == "PostgreSQL"; sqlx::raw_sql(migration).execute(&pool).await?; + sqlx::raw_sql(migration_002).execute(&pool).await?; Ok(Self { pool, is_postgres }) } From eb48165994ac365ced8ca0ad2796b28060249ef4 Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 16 Apr 2026 10:08:18 -0400 Subject: [PATCH 2/2] refactor: consolidate duplicate topic index migration The 002 migration SQL is dialect-agnostic (CREATE INDEX IF NOT EXISTS), so a single file suffices for both PostgreSQL and SQLite. Removes the duplicate _pg variant and uses a shared include_str! outside the backend match arm. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../migrations/002_add_topic_indexes.sql | 2 +- .../migrations/002_add_topic_indexes_pg.sql | 9 --------- crates/cold-sql/src/backend.rs | 16 ++++++---------- 3 files changed, 7 insertions(+), 20 deletions(-) delete mode 100644 crates/cold-sql/migrations/002_add_topic_indexes_pg.sql diff --git a/crates/cold-sql/migrations/002_add_topic_indexes.sql b/crates/cold-sql/migrations/002_add_topic_indexes.sql index 2ddcce8..0843a5c 100644 --- a/crates/cold-sql/migrations/002_add_topic_indexes.sql +++ b/crates/cold-sql/migrations/002_add_topic_indexes.sql @@ -1,6 +1,6 @@ -- Add indexes on topic1, topic2, topic3 for log filtering. -- --- topic0 already has an index (001_initial.sql). Most ERC-20/721 +-- topic0 already has an index (001_initial). Most ERC-20/721 -- Transfer lookups filter on topic1 (from) or topic2 (to), which -- previously required sequential scans. diff --git a/crates/cold-sql/migrations/002_add_topic_indexes_pg.sql b/crates/cold-sql/migrations/002_add_topic_indexes_pg.sql deleted file mode 100644 index c42ee78..0000000 --- a/crates/cold-sql/migrations/002_add_topic_indexes_pg.sql +++ /dev/null @@ -1,9 +0,0 @@ --- Add indexes on topic1, topic2, topic3 for log filtering. --- --- topic0 already has an index (001_initial_pg.sql). Most ERC-20/721 --- Transfer lookups filter on topic1 (from) or topic2 (to), which --- previously required sequential scans. - -CREATE INDEX IF NOT EXISTS idx_logs_topic1 ON logs (topic1); -CREATE INDEX IF NOT EXISTS idx_logs_topic2 ON logs (topic2); -CREATE INDEX IF NOT EXISTS idx_logs_topic3 ON logs (topic3); diff --git a/crates/cold-sql/src/backend.rs b/crates/cold-sql/src/backend.rs index 93c757b..9056da6 100644 --- a/crates/cold-sql/src/backend.rs +++ b/crates/cold-sql/src/backend.rs @@ -115,15 +115,9 @@ impl SqlColdBackend { let backend = conn.backend_name().to_owned(); drop(conn); - let (migration, migration_002) = match backend.as_str() { - "PostgreSQL" => ( - include_str!("../migrations/001_initial_pg.sql"), - include_str!("../migrations/002_add_topic_indexes_pg.sql"), - ), - "SQLite" => ( - include_str!("../migrations/001_initial.sql"), - include_str!("../migrations/002_add_topic_indexes.sql"), - ), + let migration = match backend.as_str() { + "PostgreSQL" => include_str!("../migrations/001_initial_pg.sql"), + "SQLite" => include_str!("../migrations/001_initial.sql"), other => { return Err(SqlColdError::Convert(format!( "unsupported database backend: {other}" @@ -134,7 +128,9 @@ impl SqlColdBackend { // connection that subsequent queries will use. let is_postgres = backend == "PostgreSQL"; sqlx::raw_sql(migration).execute(&pool).await?; - sqlx::raw_sql(migration_002).execute(&pool).await?; + sqlx::raw_sql(include_str!("../migrations/002_add_topic_indexes.sql")) + .execute(&pool) + .await?; Ok(Self { pool, is_postgres }) }