fix(query): preserve PG notices for statements without results
This commit is contained in:
1 parent
9c22856285
commit
20e026eea9
3 files changed
+75
-24
No files matched your search
@@ -7551,29 +7551,46 @@ pub async fn execute_query_with_max_rows(
|
||||
let start = Instant::now();
|
||||
let row_limit = query_result_row_limit(max_rows);
|
||||
|
||||
if postgres_statement_returns_rows(sql) {
|
||||
let client = checkout_postgres_client(pool, None, super::connection_timeout()).await?;
|
||||
let client = checkout_postgres_client(pool, None, super::connection_timeout()).await?;
|
||||
// Drop stale notices from infrastructure statements so only messages raised
|
||||
// by this statement are attached to its result.
|
||||
let _ = drain_postgres_notices(&client).await;
|
||||
|
||||
let result = if postgres_statement_returns_rows(sql) {
|
||||
execute_select_query(&client, sql, start, row_limit).await
|
||||
} else {
|
||||
let client = checkout_postgres_client(pool, None, super::connection_timeout()).await?;
|
||||
let affected = client.execute(sql, &[]).await.map_err(pg_error_to_string)?;
|
||||
clear_postgres_caches_after_ddl(pool, Some(&client), sql);
|
||||
client.execute(sql, &[]).await.map_err(pg_error_to_string).map(|affected| {
|
||||
clear_postgres_caches_after_ddl(pool, Some(&client), sql);
|
||||
|
||||
Ok(QueryResult {
|
||||
columns: vec![],
|
||||
column_types: Vec::new(),
|
||||
column_sortables: Vec::new(),
|
||||
spatial_columns: vec![],
|
||||
spatial_values: vec![],
|
||||
rows: vec![],
|
||||
affected_rows: affected,
|
||||
execution_time_ms: start.elapsed().as_millis(),
|
||||
truncated: false,
|
||||
session_id: None,
|
||||
has_more: false,
|
||||
elasticsearch_raw_body: None,
|
||||
messages: Vec::new(),
|
||||
QueryResult {
|
||||
columns: vec![],
|
||||
column_types: Vec::new(),
|
||||
column_sortables: Vec::new(),
|
||||
spatial_columns: vec![],
|
||||
spatial_values: vec![],
|
||||
rows: vec![],
|
||||
affected_rows: affected,
|
||||
execution_time_ms: start.elapsed().as_millis(),
|
||||
truncated: false,
|
||||
session_id: None,
|
||||
has_more: false,
|
||||
elasticsearch_raw_body: None,
|
||||
messages: Vec::new(),
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(mut result) => {
|
||||
result.messages = drain_postgres_notices(&client).await;
|
||||
Ok(result)
|
||||
}
|
||||
Err(error) => {
|
||||
// Drop notices so an errored statement's messages cannot leak into
|
||||
// the next query on this pooled connection.
|
||||
let _ = drain_postgres_notices(&client).await;
|
||||
Err(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10048,6 +10065,25 @@ mod tests {
|
||||
assert!(result.messages.iter().any(|message| message.message == "dbx notice identity regression"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore = "requires DBX_TEST_POSTGRES_URL pointing at a PostgreSQL database"]
|
||||
async fn postgres_command_query_preserves_notice_capture() {
|
||||
let url = std::env::var("DBX_TEST_POSTGRES_URL").expect("DBX_TEST_POSTGRES_URL");
|
||||
let pool = connect_with_local_timezone(&url, Duration::from_secs(10), "UTC")
|
||||
.await
|
||||
.expect("connect PostgreSQL database");
|
||||
|
||||
// `execute_query_with_max_rows` is the public command helper (used by
|
||||
// DROP DATABASE and the transfer/export fallback). A statement with no
|
||||
// result set must still attach the notices it raised.
|
||||
let result =
|
||||
execute_query_with_max_rows(&pool, "DO $$ BEGIN RAISE NOTICE 'dbx public notice regression'; END $$", None)
|
||||
.await
|
||||
.expect("execute statement with notice");
|
||||
|
||||
assert!(result.messages.iter().any(|message| message.message == "dbx public notice regression"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_notices_for_key_returns_buffered_notices_and_empties_buffer() {
|
||||
let key = ("test-host".to_string(), "9000001".to_string(), "9000001".to_string());
|
||||
|
||||
Reference in new issue
Block a user