Skip to content

Commit e7cf862

Browse files
committed
feat: support calling PostgreSQL procedures with the macros
Fixes launchbadge#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.
1 parent 76ae286 commit e7cf862

File tree

3 files changed

+31
-5
lines changed

3 files changed

+31
-5
lines changed

sqlx-core/src/postgres/connection/describe.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,15 @@ SELECT oid FROM pg_catalog.pg_type WHERE typname ILIKE $1
453453

454454
let mut nullables = Vec::new();
455455

456-
if let Some(outputs) = &explain.plan.output {
456+
if let Explain::Plan(
457+
plan @ Plan {
458+
output: Some(outputs),
459+
..
460+
},
461+
) = &explain
462+
{
457463
nullables.resize(outputs.len(), None);
458-
visit_plan(&explain.plan, outputs, &mut nullables);
464+
visit_plan(&plan, outputs, &mut nullables);
459465
}
460466

461467
Ok(nullables)
@@ -488,9 +494,13 @@ fn visit_plan(plan: &Plan, outputs: &[String], nullables: &mut Vec<Option<bool>>
488494
}
489495

490496
#[derive(serde::Deserialize)]
491-
struct Explain {
492-
#[serde(rename = "Plan")]
493-
plan: Plan,
497+
enum Explain {
498+
/// {"Plan": ...} -- returned for most statements
499+
Plan(Plan),
500+
/// The string "Utility Statement" -- returned for
501+
/// a CALL statement
502+
#[serde(rename = "Utility Statement")]
503+
UtilityStatement,
494504
}
495505

496506
#[derive(serde::Deserialize)]

tests/postgres/macros.rs

+13
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ async fn test_void() -> anyhow::Result<()> {
9696
Ok(())
9797
}
9898

99+
#[sqlx_macros::test]
100+
async fn test_call_procedure() -> anyhow::Result<()> {
101+
let mut conn = new::<Postgres>().await?;
102+
103+
let row = sqlx::query!(r#"CALL forty_two(null)"#)
104+
.fetch_one(&mut conn)
105+
.await?;
106+
107+
assert_eq!(row.forty_two, Some(42));
108+
109+
Ok(())
110+
}
111+
99112
#[sqlx_macros::test]
100113
async fn test_query_file() -> anyhow::Result<()> {
101114
let mut conn = new::<Postgres>().await?;

tests/postgres/setup.sql

+3
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ CREATE TABLE products (
3232
name TEXT,
3333
price NUMERIC CHECK (price > 0)
3434
);
35+
36+
CREATE OR REPLACE PROCEDURE forty_two(INOUT forty_two INT = NULL)
37+
LANGUAGE plpgsql AS 'begin forty_two := 42; end;';

0 commit comments

Comments
 (0)