diff --git a/sqlx-core/src/postgres/type_info.rs b/sqlx-core/src/postgres/type_info.rs index 194a2d39..8a9f7caa 100644 --- a/sqlx-core/src/postgres/type_info.rs +++ b/sqlx-core/src/postgres/type_info.rs @@ -755,6 +755,10 @@ impl TypeInfo for PgTypeInfo { fn is_null(&self) -> bool { false } + + fn is_void(&self) -> bool { + matches!(self.0, PgType::Void) + } } impl PartialEq for PgCustomType { diff --git a/sqlx-core/src/type_info.rs b/sqlx-core/src/type_info.rs index ed38c61f..72b2a5a9 100644 --- a/sqlx-core/src/type_info.rs +++ b/sqlx-core/src/type_info.rs @@ -8,4 +8,9 @@ pub trait TypeInfo: Debug + Display + Clone + PartialEq + Send + Sync { /// Common type names are `VARCHAR`, `TEXT`, or `INT`. Type names should be uppercase. They /// should be a rough approximation of how they are written in SQL in the given database. fn name(&self) -> &str; + + #[doc(hidden)] + fn is_void(&self) -> bool { + false + } } diff --git a/sqlx-macros/src/query/mod.rs b/sqlx-macros/src/query/mod.rs index e617a81c..833cc63e 100644 --- a/sqlx-macros/src/query/mod.rs +++ b/sqlx-macros/src/query/mod.rs @@ -9,7 +9,7 @@ pub use input::QueryMacroInput; use quote::{format_ident, quote}; use sqlx_core::connection::Connection; use sqlx_core::database::Database; -use sqlx_core::describe::Describe; +use sqlx_core::{column::Column, describe::Describe, type_info::TypeInfo}; use sqlx_rt::block_on; use crate::database::DatabaseExt; @@ -208,7 +208,7 @@ where let query_args = format_ident!("query_args"); - let output = if data.describe.columns().is_empty() { + let output = if data.describe.columns().iter().all(|it| it.type_info().is_void()) { let db_path = DB::db_path(); let sql = &input.src; diff --git a/src/macros.rs b/src/macros.rs index 340ffcfe..d0e2bc7a 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,7 +1,7 @@ /// Statically checked SQL query with `println!()` style syntax. /// /// This expands to an instance of [`query::Map`][crate::query::Map] that outputs an ad-hoc anonymous -/// struct type, if the query has output columns, or `()` (unit) otherwise: +/// struct type, if the query has at least one output column that is not `Void`, or `()` (unit) otherwise: /// /// ```rust,ignore /// # use sqlx::Connect; diff --git a/tests/postgres/macros.rs b/tests/postgres/macros.rs index 40ee16c4..e2fbc2d7 100644 --- a/tests/postgres/macros.rs +++ b/tests/postgres/macros.rs @@ -89,12 +89,10 @@ async fn test_text_var_char_char_n() -> anyhow::Result<()> { async fn test_void() -> anyhow::Result<()> { let mut conn = new::().await?; - let record = sqlx::query!(r#"select pg_notify('chan', 'message') as _1"#) - .fetch_one(&mut conn) + let _ = sqlx::query!(r#"select pg_notify('chan', 'message')"#) + .execute(&mut conn) .await?; - assert_eq!(record._1, Some(())); - Ok(()) }