MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / validate_readonly_query

Function validate_readonly_query

src/environmentd/src/http/mcp.rs:1175–1217  ·  view source on GitHub ↗

Validates query is a single SELECT, SHOW, or EXPLAIN statement.

(sql: &str)

Source from the content-addressed store, hash-verified

1173
1174/// Validates query is a single SELECT, SHOW, or EXPLAIN statement.
1175fn validate_readonly_query(sql: &str) -> Result<(), McpRequestError> {
1176 let sql = sql.trim();
1177 if sql.is_empty() {
1178 return Err(McpRequestError::QueryValidationFailed(
1179 "Empty query".to_string(),
1180 ));
1181 }
1182
1183 // Parse the SQL to get AST
1184 let stmts = parse(sql).map_err(|e| {
1185 McpRequestError::QueryValidationFailed(format!("Failed to parse SQL: {}", e))
1186 })?;
1187
1188 // Only allow a single statement
1189 if stmts.len() != 1 {
1190 return Err(McpRequestError::QueryValidationFailed(format!(
1191 "Only one query allowed at a time. Found {} statements.",
1192 stmts.len()
1193 )));
1194 }
1195
1196 // Allowlist: SELECT, SHOW, and every read-only EXPLAIN variant. EXPLAIN
1197 // expands to six distinct Statement variants in the parser (ExplainPlan
1198 // covers only the most common one). Listing them out exhaustively beats
1199 // matching by string prefix so a new write-capable EXPLAIN variant — were
1200 // one ever added — would have to be considered here.
1201 let stmt = &stmts[0];
1202 use mz_sql_parser::ast::Statement;
1203
1204 match &stmt.ast {
1205 Statement::Select(_)
1206 | Statement::Show(_)
1207 | Statement::ExplainPlan(_)
1208 | Statement::ExplainPushdown(_)
1209 | Statement::ExplainTimestamp(_)
1210 | Statement::ExplainSinkSchema(_)
1211 | Statement::ExplainAnalyzeObject(_)
1212 | Statement::ExplainAnalyzeCluster(_) => Ok(()),
1213 _ => Err(McpRequestError::QueryValidationFailed(
1214 "Only SELECT, SHOW, and EXPLAIN statements are allowed".to_string(),
1215 )),
1216 }
1217}
1218
1219async fn execute_query(
1220 client: &mut AuthedClient,

Callers 2

execute_queryFunction · 0.85
query_system_catalogFunction · 0.85

Calls 5

parseFunction · 0.70
trimMethod · 0.45
is_emptyMethod · 0.45
to_stringMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected