From eb481d03d37a396ff9276e5245c3bbddb4a05b05 Mon Sep 17 00:00:00 2001 From: barry3406 Date: Thu, 9 Apr 2026 13:07:42 -0700 Subject: [PATCH] test(sqlite): add regression test for ORDER BY + LIMIT nullability Covers the scenario from #4147 where ORDER BY + LIMIT routes data through an ephemeral sorter table. Verifies NOT NULL columns keep their constraint, and nullable columns stay nullable. This already passes on main (the 0.9 explain rewrite fixed it), but there was no test guarding against regression. --- tests/sqlite/describe.rs | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/sqlite/describe.rs b/tests/sqlite/describe.rs index 4c0768a5e2..49bdbd35e7 100644 --- a/tests/sqlite/describe.rs +++ b/tests/sqlite/describe.rs @@ -591,6 +591,50 @@ async fn it_describes_table_order_by() -> anyhow::Result<()> { Ok(()) } +// Regression test for https://github.com/launchbadge/sqlx/issues/4147 +// ORDER BY + LIMIT routes data through an ephemeral sorter table; +// the NOT NULL constraint must survive the round-trip. +#[sqlx_macros::test] +async fn it_describes_order_by_with_limit() -> anyhow::Result<()> { + let mut conn = new::().await?; + + let info = conn + .describe("SELECT text FROM tweet ORDER BY id DESC LIMIT 10".into_sql_str()) + .await?; + assert_eq!(info.column(0).type_info().name(), "TEXT"); + assert_eq!( + info.nullable(0), + Some(false), + "NOT NULL column should stay NOT NULL with ORDER BY + LIMIT" + ); + + let info = conn + .describe("SELECT text, is_sent FROM tweet ORDER BY id DESC LIMIT 10000".into_sql_str()) + .await?; + assert_eq!( + info.nullable(0), + Some(false), + "text should be NOT NULL with ORDER BY DESC + large LIMIT" + ); + assert_eq!( + info.nullable(1), + Some(false), + "is_sent should be NOT NULL with ORDER BY DESC + large LIMIT" + ); + + // nullable column must remain nullable + let info = conn + .describe("SELECT owner_id FROM tweet ORDER BY id DESC LIMIT 10".into_sql_str()) + .await?; + assert_eq!( + info.nullable(0), + Some(true), + "nullable column should stay nullable with ORDER BY + LIMIT" + ); + + Ok(()) +} + #[sqlx_macros::test] async fn it_describes_union() -> anyhow::Result<()> { async fn assert_union_described(