Skip to content

Commit e35484c

Browse files
fix: duplicate columns in schema cache
1 parent 4a62cc0 commit e35484c

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

crates/pgt_schema_cache/src/queries/columns.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ with
1919
available_indexes as (
2020
select
2121
unnest (ix.indkey) as attnum,
22-
ix.indisprimary as is_primary,
23-
ix.indisunique as is_unique,
22+
bool_or(ix.indisprimary) as is_primary,
23+
bool_or(ix.indisunique) as is_unique,
2424
ix.indrelid as table_oid
2525
from
2626
pg_catalog.pg_class c
2727
join pg_catalog.pg_index ix on c.oid = ix.indexrelid
2828
where
2929
c.relkind = 'i'
30+
group by table_oid, attnum
3031
)
3132
select
3233
atts.attname as name,

crates/pgt_schema_cache/src/schema_cache.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ pub trait SchemaCacheItem {
165165

166166
#[cfg(test)]
167167
mod tests {
168-
use sqlx::PgPool;
168+
use std::collections::HashSet;
169+
170+
use sqlx::{Executor, PgPool};
169171

170172
use crate::SchemaCache;
171173

@@ -175,4 +177,34 @@ mod tests {
175177
.await
176178
.expect("Couldnt' load Schema Cache");
177179
}
180+
181+
#[sqlx::test(migrator = "pgt_test_utils::MIGRATIONS")]
182+
async fn it_does_not_have_duplicate_entries(test_db: PgPool) {
183+
// we had some duplicate columns in the schema_cache because of indices including the same column multiple times.
184+
// the columns were unnested as duplicates in the query
185+
let setup = r#"
186+
CREATE TABLE public.mfa_factors (
187+
id uuid PRIMARY KEY,
188+
user_id uuid NOT NULL,
189+
factor_name text NOT NULL
190+
);
191+
192+
-- a second index on id!
193+
CREATE INDEX idx_mfa_user_factor ON public.mfa_factors(id, factor_name);
194+
"#;
195+
196+
test_db.execute(setup).await.unwrap();
197+
198+
let cache = SchemaCache::load(&test_db)
199+
.await
200+
.expect("Couldn't load Schema Cache");
201+
202+
let set: HashSet<String> = cache
203+
.columns
204+
.iter()
205+
.map(|c| format!("{}.{}.{}", c.schema_name, c.table_name, c.name))
206+
.collect();
207+
208+
assert_eq!(set.len(), cache.columns.len());
209+
}
178210
}

0 commit comments

Comments
 (0)