Skip to content

Commit 3956bfb

Browse files
committed
feat: pg_stat_user_tables
1 parent 0503bc9 commit 3956bfb

File tree

3 files changed

+105
-49
lines changed

3 files changed

+105
-49
lines changed

datafusion-postgres/src/pg_catalog.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use datafusion::prelude::{create_udf, Expr, SessionContext};
2020
use postgres_types::Oid;
2121
use tokio::sync::RwLock;
2222

23+
mod empty_table;
2324
mod pg_attribute;
2425
mod pg_class;
2526
mod pg_database;
@@ -94,6 +95,7 @@ const PG_CATALOG_VIEW_PG_SETTINGS: &str = "pg_settings";
9495
const PG_CATALOG_VIEW_PG_VIEWS: &str = "pg_views";
9596
const PG_CATALOG_VIEW_PG_MATVIEWS: &str = "pg_matviews";
9697
const PG_CATALOG_VIEW_PG_TABLES: &str = "pg_tables";
98+
const PG_CATALOG_VIEW_PG_STAT_USER_TABELS: &str = "pg_stat_user_tables";
9799

98100
/// Determine PostgreSQL table type (relkind) from DataFusion TableProvider
99101
fn get_table_type(table: &Arc<dyn TableProvider>) -> &'static str {
@@ -191,6 +193,7 @@ pub const PG_CATALOG_TABLES: &[&str] = &[
191193
PG_CATALOG_VIEW_PG_SETTINGS,
192194
PG_CATALOG_VIEW_PG_VIEWS,
193195
PG_CATALOG_VIEW_PG_MATVIEWS,
196+
PG_CATALOG_VIEW_PG_STAT_USER_TABELS,
194197
];
195198

196199
#[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
@@ -371,13 +374,10 @@ impl SchemaProvider for PgCatalogSchemaProvider {
371374
let table = pg_settings::PgSettingsView::try_new()?;
372375
Ok(Some(Arc::new(table.try_into_memtable()?)))
373376
}
374-
PG_CATALOG_VIEW_PG_VIEWS => {
375-
let table = pg_views::PgViewsTable::new();
376-
Ok(Some(Arc::new(table.try_into_memtable()?)))
377-
}
378-
PG_CATALOG_VIEW_PG_MATVIEWS => {
379-
let table = pg_views::PgMatviewsTable::new();
380-
Ok(Some(Arc::new(table.try_into_memtable()?)))
377+
PG_CATALOG_VIEW_PG_VIEWS => Ok(Some(Arc::new(pg_views::pg_views()?))),
378+
PG_CATALOG_VIEW_PG_MATVIEWS => Ok(Some(Arc::new(pg_views::pg_matviews()?))),
379+
PG_CATALOG_VIEW_PG_STAT_USER_TABELS => {
380+
Ok(Some(Arc::new(pg_views::pg_stat_user_tables()?)))
381381
}
382382

383383
_ => Ok(None),
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use datafusion::arrow::datatypes::SchemaRef;
2+
use datafusion::catalog::MemTable;
3+
use datafusion::error::Result;
4+
5+
#[derive(Debug, Clone)]
6+
pub(crate) struct EmptyTable {
7+
schema: SchemaRef,
8+
}
9+
10+
impl EmptyTable {
11+
pub(crate) fn new(schema: SchemaRef) -> Self {
12+
Self { schema }
13+
}
14+
15+
pub fn try_into_memtable(self) -> Result<MemTable> {
16+
MemTable::try_new(self.schema, vec![vec![]])
17+
}
18+
}
Lines changed: 80 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,92 @@
11
use std::sync::Arc;
22

3-
use datafusion::arrow::datatypes::{DataType, Field, Schema, SchemaRef};
3+
use datafusion::arrow::datatypes::{DataType, Field, Schema, TimeUnit};
44
use datafusion::catalog::MemTable;
55
use datafusion::error::Result;
66

7-
#[derive(Debug, Clone)]
8-
pub(crate) struct PgViewsTable {
9-
schema: SchemaRef,
10-
}
11-
12-
impl PgViewsTable {
13-
pub(crate) fn new() -> Self {
14-
// Define the schema for pg_views
15-
let schema = Arc::new(Schema::new(vec![
16-
Field::new("schemaname", DataType::Utf8, true),
17-
Field::new("viewname", DataType::Utf8, true),
18-
Field::new("viewowner", DataType::Utf8, true),
19-
Field::new("definition", DataType::Utf8, true),
20-
]));
21-
22-
Self { schema }
23-
}
7+
use super::empty_table::EmptyTable;
248

25-
pub fn try_into_memtable(self) -> Result<MemTable> {
26-
MemTable::try_new(self.schema, vec![vec![]])
27-
}
9+
pub fn pg_views() -> Result<MemTable> {
10+
let schema = Arc::new(Schema::new(vec![
11+
Field::new("schemaname", DataType::Utf8, true),
12+
Field::new("viewname", DataType::Utf8, true),
13+
Field::new("viewowner", DataType::Utf8, true),
14+
Field::new("definition", DataType::Utf8, true),
15+
]));
16+
EmptyTable::new(schema).try_into_memtable()
2817
}
2918

30-
#[derive(Debug, Clone)]
31-
pub(crate) struct PgMatviewsTable {
32-
schema: SchemaRef,
33-
}
19+
pub fn pg_matviews() -> Result<MemTable> {
20+
let schema = Arc::new(Schema::new(vec![
21+
Field::new("schemaname", DataType::Utf8, true),
22+
Field::new("matviewname", DataType::Utf8, true),
23+
Field::new("matviewowner", DataType::Utf8, true),
24+
Field::new("tablespace", DataType::Utf8, true),
25+
Field::new("hasindexes", DataType::Boolean, true),
26+
Field::new("ispopulated", DataType::Boolean, true),
27+
Field::new("definition", DataType::Utf8, true),
28+
]));
3429

35-
impl PgMatviewsTable {
36-
pub(crate) fn new() -> Self {
37-
// Define the schema for pg_matviews
38-
let schema = Arc::new(Schema::new(vec![
39-
Field::new("schemaname", DataType::Utf8, true),
40-
Field::new("matviewname", DataType::Utf8, true),
41-
Field::new("matviewowner", DataType::Utf8, true),
42-
Field::new("tablespace", DataType::Utf8, true),
43-
Field::new("hasindexes", DataType::Boolean, true),
44-
Field::new("ispopulated", DataType::Boolean, true),
45-
Field::new("definition", DataType::Utf8, true),
46-
]));
30+
EmptyTable::new(schema).try_into_memtable()
31+
}
4732

48-
Self { schema }
49-
}
33+
pub fn pg_stat_user_tables() -> Result<MemTable> {
34+
let schema = Arc::new(Schema::new(vec![
35+
Field::new("relid", DataType::Int32, false),
36+
Field::new("schemaname", DataType::Utf8, false),
37+
Field::new("relname", DataType::Utf8, false),
38+
Field::new("seq_scan", DataType::Int64, false),
39+
Field::new(
40+
"last_seq_scan",
41+
DataType::Timestamp(TimeUnit::Millisecond, None),
42+
true,
43+
),
44+
Field::new("seq_tup_read", DataType::Int64, false),
45+
Field::new("idx_scan", DataType::Int64, false),
46+
Field::new(
47+
"last_idx_scan",
48+
DataType::Timestamp(TimeUnit::Millisecond, None),
49+
true,
50+
),
51+
Field::new("idx_tup_fetch", DataType::Int64, false),
52+
Field::new("n_tup_ins", DataType::Int64, false),
53+
Field::new("n_tup_upd", DataType::Int64, false),
54+
Field::new("n_tup_del", DataType::Int64, false),
55+
Field::new("n_tup_hot_upd", DataType::Int64, false),
56+
Field::new("n_tup_newpage_upd", DataType::Int64, false),
57+
Field::new("n_live_tup", DataType::Int64, false),
58+
Field::new("n_dead_tup", DataType::Int64, false),
59+
Field::new("n_mod_since_analyze", DataType::Int64, false),
60+
Field::new("n_ins_since_vacuum", DataType::Int64, false),
61+
Field::new(
62+
"last_vacuum",
63+
DataType::Timestamp(TimeUnit::Millisecond, None),
64+
true,
65+
),
66+
Field::new(
67+
"last_autovacuum",
68+
DataType::Timestamp(TimeUnit::Millisecond, None),
69+
true,
70+
),
71+
Field::new(
72+
"last_analyze",
73+
DataType::Timestamp(TimeUnit::Millisecond, None),
74+
true,
75+
),
76+
Field::new(
77+
"last_autoanalyze",
78+
DataType::Timestamp(TimeUnit::Millisecond, None),
79+
true,
80+
),
81+
Field::new("vacuum_count", DataType::Int64, false),
82+
Field::new("autovacuum_count", DataType::Int64, false),
83+
Field::new("analyze_count", DataType::Int64, false),
84+
Field::new("autoanalyze_count", DataType::Int64, false),
85+
Field::new("total_vacuum_time", DataType::Float64, false),
86+
Field::new("total_autovacuum_time", DataType::Float64, false),
87+
Field::new("total_analyze_time", DataType::Float64, false),
88+
Field::new("total_autoanalyze_time", DataType::Float64, false),
89+
]));
5090

51-
pub fn try_into_memtable(self) -> Result<MemTable> {
52-
MemTable::try_new(self.schema, vec![vec![]])
53-
}
91+
EmptyTable::new(schema).try_into_memtable()
5492
}

0 commit comments

Comments
 (0)