MCPcopy Create free account
hub / github.com/erans/pgsqlite / execute_query

Method execute_query

src/query/executor.rs:180–256  ·  view source on GitHub ↗
(
        framed: &mut Framed<T, crate::protocol::PostgresCodec>,
        db: &Arc<DbHandler>,
        session: &Arc<SessionState>,
        query: &str,
        query_router: Option<&Arc<QueryRouter>>

Source from the content-addressed store, hash-verified

178 }
179 }
180 pub async fn execute_query<T>(
181 framed: &mut Framed<T, crate::protocol::PostgresCodec>,
182 db: &Arc<DbHandler>,
183 session: &Arc<SessionState>,
184 query: &str,
185 query_router: Option<&Arc<QueryRouter>>,
186 ) -> Result<(), PgSqliteError>
187 where
188 T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send,
189 {
190 println!("EXECUTOR: execute_query called with: '{}'", query);
191 // Executing query
192
193 // Strip SQL comments first to avoid parsing issues
194 let cleaned_query = crate::query::strip_sql_comments(query);
195 let query_to_execute = cleaned_query.trim();
196
197 // Check if query is empty after comment stripping
198 if query_to_execute.is_empty() {
199 return Err(PgSqliteError::Protocol(error_message!("Empty query").into_owned()));
200 }
201
202 // Handle PostgreSQL DEALLOCATE commands (used for prepared statement cleanup)
203 let query_upper = query_to_execute.to_uppercase();
204 if query_upper.starts_with("DEALLOCATE") {
205 debug!("DEALLOCATE command - treating as successful no-op (SQLite manages prepared statements automatically)");
206 // Send CommandComplete for successful DEALLOCATE
207 let msg = BackendMessage::CommandComplete { tag: error_message!("DEALLOCATE").into_owned() };
208 framed.send(msg).await.map_err(PgSqliteError::Io)?;
209 return Ok(());
210 }
211
212 // debug!("Executing query: {}", query_to_execute);
213
214 // Check for Python-style parameters and provide helpful error
215 use crate::query::parameter_parser::ParameterParser;
216 let python_params = ParameterParser::find_python_parameters(query_to_execute);
217 if !python_params.is_empty() {
218 let error_msg = format!(
219 "Python-style parameters detected: {python_params:?}. pgsqlite requires parameter values to be substituted before execution. This usually means psycopg2 client-side substitution failed. Please ensure parameters are properly bound when executing the query."
220 );
221 debug!("⚠️ {}", error_msg);
222 debug!("Query: {}", query_to_execute);
223 return Err(PgSqliteError::Protocol(error_msg));
224 }
225
226 // Check if query contains multiple statements
227 let trimmed = query_to_execute.trim();
228 if trimmed.contains(';') {
229 // Split by semicolon and execute each statement
230 let statements: Vec<&str> = trimmed.split(';')
231 .map(|s| s.trim())
232 .filter(|s| !s.is_empty())
233 .collect();
234
235 // Handle empty query case (just semicolon) - SQLAlchemy uses ";" for ping
236 if statements.is_empty() {
237 debug!("Empty query (just semicolon) - treating as successful no-op");

Callers 7

execute_selectMethod · 0.45
execute_dmlMethod · 0.45
execute_genericMethod · 0.45
queryMethod · 0.45
executeMethod · 0.45

Calls 5

strip_sql_commentsFunction · 0.85
global_string_optimizerFunction · 0.85
get_command_tagMethod · 0.80
is_emptyMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected