feat: support calling PostgreSQL procedures with the macros

Fixes #1449 (I think). I verified that the code fixes the new test.

I used INOUT in setup.sql because older versions of Postgres don't
support OUT parameters.
This commit is contained in:
Bram Geron 2023-03-03 07:34:17 +01:00 committed by Austin Bonander
parent bb2baf2183
commit 1ff6a2ac94
3 changed files with 31 additions and 5 deletions

View File

@ -451,9 +451,15 @@ WHERE rngtypid = $1
let mut nullables = Vec::new();
if let Some(outputs) = &explain.plan.output {
if let Explain::Plan(
plan @ Plan {
output: Some(outputs),
..
},
) = &explain
{
nullables.resize(outputs.len(), None);
visit_plan(&explain.plan, outputs, &mut nullables);
visit_plan(&plan, outputs, &mut nullables);
}
Ok(nullables)
@ -486,9 +492,13 @@ fn visit_plan(plan: &Plan, outputs: &[String], nullables: &mut Vec<Option<bool>>
}
#[derive(serde::Deserialize)]
struct Explain {
#[serde(rename = "Plan")]
plan: Plan,
enum Explain {
/// {"Plan": ...} -- returned for most statements
Plan(Plan),
/// The string "Utility Statement" -- returned for
/// a CALL statement
#[serde(rename = "Utility Statement")]
UtilityStatement,
}
#[derive(serde::Deserialize)]

View File

@ -96,6 +96,19 @@ async fn test_void() -> anyhow::Result<()> {
Ok(())
}
#[sqlx_macros::test]
async fn test_call_procedure() -> anyhow::Result<()> {
let mut conn = new::<Postgres>().await?;
let row = sqlx::query!(r#"CALL forty_two(null)"#)
.fetch_one(&mut conn)
.await?;
assert_eq!(row.forty_two, Some(42));
Ok(())
}
#[sqlx_macros::test]
async fn test_query_file() -> anyhow::Result<()> {
let mut conn = new::<Postgres>().await?;

View File

@ -41,3 +41,6 @@ CREATE TABLE products (
name TEXT,
price NUMERIC CHECK (price > 0)
);
CREATE OR REPLACE PROCEDURE forty_two(INOUT forty_two INT = NULL)
LANGUAGE plpgsql AS 'begin forty_two := 42; end;';