@@ -34,41 +34,47 @@ pub async fn get_replication_lag(
3434 client : & Client ,
3535 subscription_name : Option < & str > ,
3636) -> Result < Vec < SourceReplicationStats > > {
37- let query = if let Some ( sub_name) = subscription_name {
38- format ! (
39- "SELECT
40- application_name,
41- state,
42- sent_lsn::text,
43- write_lsn::text,
44- flush_lsn::text,
45- replay_lsn::text,
46- EXTRACT(EPOCH FROM write_lag) * 1000 as write_lag_ms,
47- EXTRACT(EPOCH FROM flush_lag) * 1000 as flush_lag_ms,
48- EXTRACT(EPOCH FROM replay_lag) * 1000 as replay_lag_ms
49- FROM pg_stat_replication
50- WHERE application_name = '{}'" ,
51- sub_name
52- )
53- } else {
54- "SELECT
55- application_name,
56- state,
57- sent_lsn::text,
58- write_lsn::text,
59- flush_lsn::text,
60- replay_lsn::text,
61- EXTRACT(EPOCH FROM write_lag) * 1000 as write_lag_ms,
62- EXTRACT(EPOCH FROM flush_lag) * 1000 as flush_lag_ms,
63- EXTRACT(EPOCH FROM replay_lag) * 1000 as replay_lag_ms
64- FROM pg_stat_replication"
65- . to_string ( )
66- } ;
37+ if let Some ( name) = subscription_name {
38+ crate :: utils:: validate_postgres_identifier ( name) . context ( "Invalid subscription name" ) ?;
39+ }
6740
68- let rows = client
69- . query ( & query, & [ ] )
70- . await
71- . context ( "Failed to query replication statistics" ) ?;
41+ let rows = if let Some ( sub_name) = subscription_name {
42+ client
43+ . query (
44+ "SELECT
45+ application_name,
46+ state,
47+ sent_lsn::text,
48+ write_lsn::text,
49+ flush_lsn::text,
50+ replay_lsn::text,
51+ EXTRACT(EPOCH FROM write_lag) * 1000 as write_lag_ms,
52+ EXTRACT(EPOCH FROM flush_lag) * 1000 as flush_lag_ms,
53+ EXTRACT(EPOCH FROM replay_lag) * 1000 as replay_lag_ms
54+ FROM pg_stat_replication
55+ WHERE application_name = $1" ,
56+ & [ & sub_name] ,
57+ )
58+ . await
59+ } else {
60+ client
61+ . query (
62+ "SELECT
63+ application_name,
64+ state,
65+ sent_lsn::text,
66+ write_lsn::text,
67+ flush_lsn::text,
68+ replay_lsn::text,
69+ EXTRACT(EPOCH FROM write_lag) * 1000 as write_lag_ms,
70+ EXTRACT(EPOCH FROM flush_lag) * 1000 as flush_lag_ms,
71+ EXTRACT(EPOCH FROM replay_lag) * 1000 as replay_lag_ms
72+ FROM pg_stat_replication" ,
73+ & [ ] ,
74+ )
75+ . await
76+ }
77+ . context ( "Failed to query replication statistics" ) ?;
7278
7379 let mut stats = Vec :: new ( ) ;
7480 for row in rows {
@@ -94,33 +100,39 @@ pub async fn get_subscription_status(
94100 client : & Client ,
95101 subscription_name : Option < & str > ,
96102) -> Result < Vec < SubscriptionStats > > {
97- let query = if let Some ( sub_name) = subscription_name {
98- format ! (
99- "SELECT
100- subname,
101- pid,
102- received_lsn::text,
103- latest_end_lsn::text,
104- srsubstate
105- FROM pg_stat_subscription
106- WHERE subname = '{}'" ,
107- sub_name
108- )
109- } else {
110- "SELECT
111- subname,
112- pid,
113- received_lsn::text,
114- latest_end_lsn::text,
115- srsubstate
116- FROM pg_stat_subscription"
117- . to_string ( )
118- } ;
103+ if let Some ( name) = subscription_name {
104+ crate :: utils:: validate_postgres_identifier ( name) . context ( "Invalid subscription name" ) ?;
105+ }
119106
120- let rows = client
121- . query ( & query, & [ ] )
122- . await
123- . context ( "Failed to query subscription statistics" ) ?;
107+ let rows = if let Some ( sub_name) = subscription_name {
108+ client
109+ . query (
110+ "SELECT
111+ subname,
112+ pid,
113+ received_lsn::text,
114+ latest_end_lsn::text,
115+ srsubstate
116+ FROM pg_stat_subscription
117+ WHERE subname = $1" ,
118+ & [ & sub_name] ,
119+ )
120+ . await
121+ } else {
122+ client
123+ . query (
124+ "SELECT
125+ subname,
126+ pid,
127+ received_lsn::text,
128+ latest_end_lsn::text,
129+ srsubstate
130+ FROM pg_stat_subscription" ,
131+ & [ ] ,
132+ )
133+ . await
134+ }
135+ . context ( "Failed to query subscription statistics" ) ?;
124136
125137 let mut stats = Vec :: new ( ) ;
126138 for row in rows {
0 commit comments