From e3859516f9d403c8e7b2d8b8387cb1431308b5ce Mon Sep 17 00:00:00 2001 From: Matthew Nibecker Date: Mon, 29 Dec 2025 13:15:37 -0800 Subject: [PATCH] vector: report const as null if base value is null When getting the value of a primitive const at a given slot, report the value as null if the base value is null. --- runtime/ztests/expr/arith-divide-by-zero.yaml | 15 +++++++++++++++ vector/bool.go | 2 +- vector/bytes.go | 2 +- vector/float.go | 2 +- vector/int.go | 2 +- vector/ip.go | 2 +- vector/net.go | 2 +- vector/string.go | 2 +- vector/type.go | 2 +- vector/uint.go | 2 +- 10 files changed, 24 insertions(+), 9 deletions(-) diff --git a/runtime/ztests/expr/arith-divide-by-zero.yaml b/runtime/ztests/expr/arith-divide-by-zero.yaml index c18f4d6559..802b66ad48 100644 --- a/runtime/ztests/expr/arith-divide-by-zero.yaml +++ b/runtime/ztests/expr/arith-divide-by-zero.yaml @@ -1,3 +1,4 @@ +# XXX This file should test floats but #6474 needs to be fixed first. spq: values a/b, a%b vector: true @@ -14,3 +15,17 @@ output: | null::uint64 error("divide by zero") error("divide by zero") + +--- + +# Check the divide by zero logic on a const null returns a null. +spq: | + values + 1/null::int64, + 1::uint64/null::uint64 + +vector: true + +output: | + null::int64 + null::uint64 diff --git a/vector/bool.go b/vector/bool.go index a4680e1c5f..e6f46e29a6 100644 --- a/vector/bool.go +++ b/vector/bool.go @@ -81,7 +81,7 @@ func BoolValue(vec Any, slot uint32) (bool, bool) { case *Bool: return vec.Bits.IsSet(slot), vec.Nulls.IsSet(slot) case *Const: - return vec.Value().Ptr().AsBool(), vec.Nulls.IsSet(slot) + return vec.Value().Ptr().AsBool(), vec.val.IsNull() || vec.Nulls.IsSet(slot) case *Dict: if vec.Nulls.IsSet(slot) { return false, true diff --git a/vector/bytes.go b/vector/bytes.go index 84851eaa1d..717dd89bd6 100644 --- a/vector/bytes.go +++ b/vector/bytes.go @@ -58,7 +58,7 @@ func BytesValue(val Any, slot uint32) ([]byte, bool) { return nil, true } s, _ := val.AsBytes() - return s, false + return s, val.val.IsNull() case *Dict: if val.Nulls.IsSet(slot) { return nil, true diff --git a/vector/float.go b/vector/float.go index aec22dd00e..49ba3db0c4 100644 --- a/vector/float.go +++ b/vector/float.go @@ -60,7 +60,7 @@ func FloatValue(vec Any, slot uint32) (float64, bool) { case *Float: return vec.Value(slot), vec.Nulls.IsSet(slot) case *Const: - return vec.Value().Ptr().Float(), vec.Nulls.IsSet(slot) + return vec.Value().Ptr().Float(), vec.val.IsNull() || vec.Nulls.IsSet(slot) case *Dict: if vec.Nulls.IsSet(slot) { return 0, true diff --git a/vector/int.go b/vector/int.go index 4a99254ccc..7ef0f43384 100644 --- a/vector/int.go +++ b/vector/int.go @@ -56,7 +56,7 @@ func IntValue(vec Any, slot uint32) (int64, bool) { case *Int: return vec.Value(slot), vec.Nulls.IsSet(slot) case *Const: - return vec.val.Int(), vec.Nulls.IsSet(slot) + return vec.val.Int(), vec.val.IsNull() || vec.Nulls.IsSet(slot) case *Dict: if vec.Nulls.IsSet(slot) { return 0, true diff --git a/vector/ip.go b/vector/ip.go index 8050b27483..ed54c85f92 100644 --- a/vector/ip.go +++ b/vector/ip.go @@ -44,7 +44,7 @@ func IPValue(val Any, slot uint32) (netip.Addr, bool) { return netip.Addr{}, true } b, _ := val.AsBytes() - return super.DecodeIP(b), false + return super.DecodeIP(b), val.val.IsNull() case *Dict: if val.Nulls.IsSet(slot) { return netip.Addr{}, true diff --git a/vector/net.go b/vector/net.go index 1c07a898d1..1fcebf49bf 100644 --- a/vector/net.go +++ b/vector/net.go @@ -44,7 +44,7 @@ func NetValue(val Any, slot uint32) (netip.Prefix, bool) { return netip.Prefix{}, true } s, _ := val.AsBytes() - return super.DecodeNet(s), false + return super.DecodeNet(s), val.val.IsNull() case *Dict: if val.Nulls.IsSet(slot) { return netip.Prefix{}, true diff --git a/vector/string.go b/vector/string.go index d2f2924e0e..93253bc6de 100644 --- a/vector/string.go +++ b/vector/string.go @@ -61,7 +61,7 @@ func StringValue(val Any, slot uint32) (string, bool) { return "", true } s, _ := val.AsString() - return s, false + return s, val.val.IsNull() case *Dict: if val.Nulls.IsSet(slot) { return "", true diff --git a/vector/type.go b/vector/type.go index 52b508ef77..4a51af4e1c 100644 --- a/vector/type.go +++ b/vector/type.go @@ -58,7 +58,7 @@ func TypeValueValue(val Any, slot uint32) ([]byte, bool) { return nil, true } s, _ := val.AsBytes() - return s, false + return s, val.val.IsNull() case *Dict: if val.Nulls.IsSet(slot) { return nil, true diff --git a/vector/uint.go b/vector/uint.go index 9570fc58e2..ec8ece13fc 100644 --- a/vector/uint.go +++ b/vector/uint.go @@ -56,7 +56,7 @@ func UintValue(vec Any, slot uint32) (uint64, bool) { case *Uint: return vec.Value(slot), vec.Nulls.IsSet(slot) case *Const: - return vec.Value().Ptr().Uint(), vec.Nulls.IsSet(slot) + return vec.Value().Ptr().Uint(), vec.val.IsNull() || vec.Nulls.IsSet(slot) case *Dict: if vec.Nulls.IsSet(slot) { return 0, true