Skip to content

Commit c20a630

Browse files
authored
node/bin/graphman: New command analyze
Introduces a new Graphman analyze command that calls SQL ANALYZE for the given entity table. Closes #3152
1 parent 4159eae commit c20a630

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

node/src/bin/manager.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,13 @@ pub enum StatsCommand {
349349
/// The name of a table to fully count
350350
table: Option<String>,
351351
},
352+
/// Perform a SQL ANALYZE in a Entity table
353+
Analyze {
354+
/// The id of the deployment
355+
id: String,
356+
/// The name of the Entity to ANALYZE
357+
entity: String,
358+
},
352359
}
353360

354361
impl From<Opt> for config::Opt {
@@ -695,6 +702,11 @@ async fn main() {
695702
commands::stats::account_like(ctx.pools(), clear, table)
696703
}
697704
Show { nsp, table } => commands::stats::show(ctx.pools(), nsp, table),
705+
Analyze { id, entity } => {
706+
let store = ctx.store();
707+
let subgraph_store = store.subgraph_store();
708+
commands::stats::analyze(subgraph_store, id, entity).await
709+
}
698710
}
699711
}
700712
};

node/src/manager/commands/stats.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
use std::collections::HashMap;
2+
use std::sync::Arc;
23

34
use diesel::r2d2::ConnectionManager;
45
use diesel::r2d2::PooledConnection;
56
use diesel::sql_query;
67
use diesel::sql_types::{Integer, Text};
78
use diesel::PgConnection;
89
use diesel::RunQueryDsl;
10+
use graph::components::store::EntityType;
911
use graph::prelude::anyhow;
1012
use graph::prelude::anyhow::bail;
13+
use graph::prelude::DeploymentHash;
1114
use graph_store_postgres::command_support::catalog::Site;
1215
use graph_store_postgres::command_support::{catalog as store_catalog, SqlName};
1316
use graph_store_postgres::connection_pool::ConnectionPool;
1417
use graph_store_postgres::Shard;
18+
use graph_store_postgres::SubgraphStore;
1519
use graph_store_postgres::PRIMARY_SHARD;
1620

1721
fn parse_table_name(table: &str) -> Result<(&str, SqlName), anyhow::Error> {
@@ -151,3 +155,22 @@ pub fn show(
151155

152156
Ok(())
153157
}
158+
159+
pub async fn analyze(
160+
store: Arc<SubgraphStore>,
161+
hash: String,
162+
entity_name: String,
163+
) -> Result<(), anyhow::Error> {
164+
println!("Running ANALYZE for {entity_name} entity");
165+
let entity_type = EntityType::new(entity_name);
166+
let deployment_hash = DeploymentHash::new(hash).map_err(|malformed_hash| {
167+
anyhow!(
168+
"Subgraph hash must be a valid IPFS hash: {}",
169+
malformed_hash
170+
)
171+
})?;
172+
store
173+
.analyze(&deployment_hash, entity_type)
174+
.await
175+
.map_err(|e| anyhow!(e))
176+
}

store/postgres/src/deployment_store.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,24 @@ impl DeploymentStore {
675675
})
676676
.await
677677
}
678+
679+
/// Runs the SQL `ANALYZE` command in a table.
680+
pub(crate) async fn analyze(
681+
&self,
682+
site: Arc<Site>,
683+
entity_type: EntityType,
684+
) -> Result<(), StoreError> {
685+
let store = self.clone();
686+
self.with_conn(move |conn, _| {
687+
let layout = store.layout(conn, site)?;
688+
let table = layout.table_for_entity(&entity_type)?;
689+
let table_name = &table.qualified_name;
690+
let sql = format!("analyze {table_name}");
691+
conn.execute(&sql)?;
692+
Ok(())
693+
})
694+
.await
695+
}
678696
}
679697

680698
/// Methods that back the trait `graph::components::Store`, but have small

store/postgres/src/subgraph_store.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use graph::{
1616
components::{
1717
server::index_node::VersionInfo,
1818
store::{
19-
self, DeploymentLocator, EnsLookup as EnsLookupTrait,
19+
self, DeploymentLocator, EnsLookup as EnsLookupTrait, EntityType,
2020
WritableStore as WritableStoreTrait,
2121
},
2222
},
@@ -947,6 +947,15 @@ impl SubgraphStoreInner {
947947
)
948948
.await;
949949
}
950+
951+
pub async fn analyze(
952+
&self,
953+
id: &DeploymentHash,
954+
entity_type: EntityType,
955+
) -> Result<(), StoreError> {
956+
let (store, site) = self.store(&id)?;
957+
store.analyze(site, entity_type).await
958+
}
950959
}
951960

952961
struct EnsLookup {

0 commit comments

Comments
 (0)