Skip to content

Commit bd3eb94

Browse files
arlyonabonander
authored andcommitted
fix(#2407): respect the HaltIfNull opcode when determining nullability
1 parent 15458fa commit bd3eb94

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

sqlx-sqlite/src/connection/explain.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ const OP_CONCAT: &str = "Concat";
125125
const OP_OFFSET_LIMIT: &str = "OffsetLimit";
126126
const OP_RESULT_ROW: &str = "ResultRow";
127127
const OP_HALT: &str = "Halt";
128+
const OP_HALT_IF_NULL: &str = "HaltIfNull";
128129

129130
const MAX_LOOP_COUNT: u8 = 2;
130131

@@ -942,6 +943,16 @@ pub(super) fn explain(
942943
state.r.insert(p2, RegDataType::Single(ColumnType::null()));
943944
}
944945

946+
// if there is a value in p3, and the query passes, then
947+
// we know that it is not nullable
948+
OP_HALT_IF_NULL => {
949+
if let Some(RegDataType::Single(ColumnType::Single { nullable, .. })) =
950+
state.r.get_mut(&p3)
951+
{
952+
*nullable = Some(false);
953+
}
954+
}
955+
945956
OP_FUNCTION => {
946957
// r[p1] = func( _ )
947958
match from_utf8(p4).map_err(Error::protocol)? {

tests/sqlite/describe.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,22 @@ async fn it_describes_insert_with_returning() -> anyhow::Result<()> {
250250
Ok(())
251251
}
252252

253+
#[sqlx_macros::test]
254+
async fn it_describes_bound_columns_non_null() -> anyhow::Result<()> {
255+
let mut conn = new::<Sqlite>().await?;
256+
let d = conn
257+
.describe("INSERT INTO tweet (id, text) VALUES ($1, $2) returning *")
258+
.await?;
259+
260+
assert_eq!(d.columns().len(), 4);
261+
assert_eq!(d.column(0).type_info().name(), "INTEGER");
262+
assert_eq!(d.nullable(0), Some(false));
263+
assert_eq!(d.column(1).type_info().name(), "TEXT");
264+
assert_eq!(d.nullable(1), Some(false));
265+
266+
Ok(())
267+
}
268+
253269
#[sqlx_macros::test]
254270
async fn it_describes_update_with_returning() -> anyhow::Result<()> {
255271
let mut conn = new::<Sqlite>().await?;

0 commit comments

Comments
 (0)