Skip to content

Commit 335f264

Browse files
committed
node, store: Make catalog::stats a method on Catalog
1 parent 4cf610d commit 335f264

File tree

4 files changed

+71
-68
lines changed

4 files changed

+71
-68
lines changed

node/src/manager/commands/stats.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use diesel::PgConnection;
1010
use graph::components::store::DeploymentLocator;
1111
use graph::components::store::VersionStats;
1212
use graph::prelude::anyhow;
13+
use graph::prelude::CheapClone as _;
1314
use graph_store_postgres::command_support::catalog as store_catalog;
1415
use graph_store_postgres::command_support::catalog::Site;
1516
use graph_store_postgres::ConnectionPool;
@@ -20,7 +21,7 @@ use graph_store_postgres::PRIMARY_SHARD;
2021
fn site_and_conn(
2122
pools: HashMap<Shard, ConnectionPool>,
2223
search: &DeploymentSearch,
23-
) -> Result<(Site, PooledConnection<ConnectionManager<PgConnection>>), anyhow::Error> {
24+
) -> Result<(Arc<Site>, PooledConnection<ConnectionManager<PgConnection>>), anyhow::Error> {
2425
let primary_pool = pools.get(&*PRIMARY_SHARD).unwrap();
2526
let locator = search.locate_unique(primary_pool)?;
2627

@@ -30,6 +31,7 @@ fn site_and_conn(
3031
let site = conn
3132
.locate_site(locator)?
3233
.ok_or_else(|| anyhow!("deployment `{}` does not exist", search))?;
34+
let site = Arc::new(site);
3335

3436
let conn = pools.get(&site.shard).unwrap().get()?;
3537

@@ -96,7 +98,8 @@ pub fn show(
9698
) -> Result<(), anyhow::Error> {
9799
let (site, mut conn) = site_and_conn(pools, search)?;
98100

99-
let stats = store_catalog::stats(&mut conn, &site)?;
101+
let catalog = store_catalog::Catalog::load(&mut conn, site.cheap_clone(), false, vec![])?;
102+
let stats = catalog.stats(&mut conn)?;
100103

101104
let account_like = store_catalog::account_like(&mut conn, &site)?;
102105

store/postgres/src/catalog.rs

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,70 @@ impl Catalog {
269269
MINMAX_OPS
270270
}
271271
}
272+
273+
pub fn stats(&self, conn: &mut PgConnection) -> Result<Vec<VersionStats>, StoreError> {
274+
#[derive(Queryable, QueryableByName)]
275+
pub struct DbStats {
276+
#[diesel(sql_type = BigInt)]
277+
pub entities: i64,
278+
#[diesel(sql_type = BigInt)]
279+
pub versions: i64,
280+
#[diesel(sql_type = Text)]
281+
pub tablename: String,
282+
/// The ratio `entities / versions`
283+
#[diesel(sql_type = Double)]
284+
pub ratio: f64,
285+
#[diesel(sql_type = Nullable<Integer>)]
286+
pub last_pruned_block: Option<i32>,
287+
}
288+
289+
impl From<DbStats> for VersionStats {
290+
fn from(s: DbStats) -> Self {
291+
VersionStats {
292+
entities: s.entities,
293+
versions: s.versions,
294+
tablename: s.tablename,
295+
ratio: s.ratio,
296+
last_pruned_block: s.last_pruned_block,
297+
}
298+
}
299+
}
300+
301+
// Get an estimate of number of rows (pg_class.reltuples) and number of
302+
// distinct entities (based on the planners idea of how many distinct
303+
// values there are in the `id` column) See the [Postgres
304+
// docs](https://www.postgresql.org/docs/current/view-pg-stats.html) for
305+
// the precise meaning of n_distinct
306+
let query = "select case when s.n_distinct < 0 then (- s.n_distinct * c.reltuples)::int8
307+
else s.n_distinct::int8
308+
end as entities,
309+
c.reltuples::int8 as versions,
310+
c.relname as tablename,
311+
case when c.reltuples = 0 then 0::float8
312+
when s.n_distinct < 0 then (-s.n_distinct)::float8
313+
else greatest(s.n_distinct, 1)::float8 / c.reltuples::float8
314+
end as ratio,
315+
ts.last_pruned_block
316+
from pg_namespace n, pg_class c, pg_stats s
317+
left outer join subgraphs.table_stats ts
318+
on (ts.table_name = s.tablename
319+
and ts.deployment = $1)
320+
where n.nspname = $2
321+
and c.relnamespace = n.oid
322+
and s.schemaname = n.nspname
323+
and s.attname = 'id'
324+
and c.relname = s.tablename
325+
order by c.relname"
326+
.to_string();
327+
328+
let stats = sql_query(query)
329+
.bind::<Integer, _>(self.site.id)
330+
.bind::<Text, _>(self.site.namespace.as_str())
331+
.load::<DbStats>(conn)
332+
.map_err(StoreError::from)?;
333+
334+
Ok(stats.into_iter().map(|s| s.into()).collect())
335+
}
272336
}
273337

274338
fn get_text_columns(
@@ -764,70 +828,6 @@ pub(crate) fn drop_index(
764828
Ok(())
765829
}
766830

767-
pub fn stats(conn: &mut PgConnection, site: &Site) -> Result<Vec<VersionStats>, StoreError> {
768-
#[derive(Queryable, QueryableByName)]
769-
pub struct DbStats {
770-
#[diesel(sql_type = BigInt)]
771-
pub entities: i64,
772-
#[diesel(sql_type = BigInt)]
773-
pub versions: i64,
774-
#[diesel(sql_type = Text)]
775-
pub tablename: String,
776-
/// The ratio `entities / versions`
777-
#[diesel(sql_type = Double)]
778-
pub ratio: f64,
779-
#[diesel(sql_type = Nullable<Integer>)]
780-
pub last_pruned_block: Option<i32>,
781-
}
782-
783-
impl From<DbStats> for VersionStats {
784-
fn from(s: DbStats) -> Self {
785-
VersionStats {
786-
entities: s.entities,
787-
versions: s.versions,
788-
tablename: s.tablename,
789-
ratio: s.ratio,
790-
last_pruned_block: s.last_pruned_block,
791-
}
792-
}
793-
}
794-
795-
// Get an estimate of number of rows (pg_class.reltuples) and number of
796-
// distinct entities (based on the planners idea of how many distinct
797-
// values there are in the `id` column) See the [Postgres
798-
// docs](https://www.postgresql.org/docs/current/view-pg-stats.html) for
799-
// the precise meaning of n_distinct
800-
let query = "select case when s.n_distinct < 0 then (- s.n_distinct * c.reltuples)::int8
801-
else s.n_distinct::int8
802-
end as entities,
803-
c.reltuples::int8 as versions,
804-
c.relname as tablename,
805-
case when c.reltuples = 0 then 0::float8
806-
when s.n_distinct < 0 then (-s.n_distinct)::float8
807-
else greatest(s.n_distinct, 1)::float8 / c.reltuples::float8
808-
end as ratio,
809-
ts.last_pruned_block
810-
from pg_namespace n, pg_class c, pg_stats s
811-
left outer join subgraphs.table_stats ts
812-
on (ts.table_name = s.tablename
813-
and ts.deployment = $1)
814-
where n.nspname = $2
815-
and c.relnamespace = n.oid
816-
and s.schemaname = n.nspname
817-
and s.attname = 'id'
818-
and c.relname = s.tablename
819-
order by c.relname"
820-
.to_string();
821-
822-
let stats = sql_query(query)
823-
.bind::<Integer, _>(site.id)
824-
.bind::<Text, _>(site.namespace.as_str())
825-
.load::<DbStats>(conn)
826-
.map_err(StoreError::from)?;
827-
828-
Ok(stats.into_iter().map(|s| s.into()).collect())
829-
}
830-
831831
/// Return by how much the slowest replica connected to the database `conn`
832832
/// is lagging. The returned value has millisecond precision. If the
833833
/// database has no replicas, return `0`

store/postgres/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub use self::subgraph_store::{unused, DeploymentPlacer, Shard, SubgraphStore, P
7373
pub mod command_support {
7474
pub mod catalog {
7575
pub use crate::block_store::primary as block_store;
76-
pub use crate::catalog::{account_like, stats};
76+
pub use crate::catalog::{account_like, Catalog};
7777
pub use crate::copy::{copy_state, copy_table_state};
7878
pub use crate::primary::{
7979
active_copies, deployment_schemas, ens_names, subgraph, subgraph_deployment_assignment,

store/postgres/src/relational/prune.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ impl Layout {
267267
reporter.finish_analyze_table(table.name.as_str());
268268
cancel.check_cancel()?;
269269
}
270-
let stats = catalog::stats(conn, &self.site)?;
270+
let stats = self.catalog.stats(conn)?;
271271

272272
let analyzed: Vec<_> = tables.iter().map(|table| table.name.as_str()).collect();
273273
reporter.finish_analyze(&stats, &analyzed);

0 commit comments

Comments
 (0)