fix(#2407): respect the HaltIfNull opcode when determining nullability

This commit is contained in:
Alexander Lyon 2023-03-17 00:06:30 +00:00 committed by Austin Bonander
parent 15458fa9d6
commit bd3eb94737
2 changed files with 27 additions and 0 deletions

View file

@ -125,6 +125,7 @@ const OP_CONCAT: &str = "Concat";
const OP_OFFSET_LIMIT: &str = "OffsetLimit";
const OP_RESULT_ROW: &str = "ResultRow";
const OP_HALT: &str = "Halt";
const OP_HALT_IF_NULL: &str = "HaltIfNull";
const MAX_LOOP_COUNT: u8 = 2;
@ -942,6 +943,16 @@ pub(super) fn explain(
state.r.insert(p2, RegDataType::Single(ColumnType::null()));
}
// if there is a value in p3, and the query passes, then
// we know that it is not nullable
OP_HALT_IF_NULL => {
if let Some(RegDataType::Single(ColumnType::Single { nullable, .. })) =
state.r.get_mut(&p3)
{
*nullable = Some(false);
}
}
OP_FUNCTION => {
// r[p1] = func( _ )
match from_utf8(p4).map_err(Error::protocol)? {

View file

@ -250,6 +250,22 @@ async fn it_describes_insert_with_returning() -> anyhow::Result<()> {
Ok(())
}
#[sqlx_macros::test]
async fn it_describes_bound_columns_non_null() -> anyhow::Result<()> {
let mut conn = new::<Sqlite>().await?;
let d = conn
.describe("INSERT INTO tweet (id, text) VALUES ($1, $2) returning *")
.await?;
assert_eq!(d.columns().len(), 4);
assert_eq!(d.column(0).type_info().name(), "INTEGER");
assert_eq!(d.nullable(0), Some(false));
assert_eq!(d.column(1).type_info().name(), "TEXT");
assert_eq!(d.nullable(1), Some(false));
Ok(())
}
#[sqlx_macros::test]
async fn it_describes_update_with_returning() -> anyhow::Result<()> {
let mut conn = new::<Sqlite>().await?;