diff --git a/runtime/vam/expr/logic.go b/runtime/vam/expr/logic.go index faf6d3759..94e6a10ba 100644 --- a/runtime/vam/expr/logic.go +++ b/runtime/vam/expr/logic.go @@ -118,15 +118,7 @@ func (o *Or) eval(vecs ...vector.Any) vector.Any { if _, ok := rhs.(*vector.Error); ok { return o.orError(rhs, lhs) } - blhs, brhs := toBool(lhs), toBool(rhs) - bits := bitvec.Or(blhs.Bits, brhs.Bits) - if blhs.Nulls.IsZero() && brhs.Nulls.IsZero() { - // Fast path involves no nulls. - return vector.NewBool(bits, bitvec.Zero) - } - nulls := bitvec.Or(blhs.Nulls, brhs.Nulls) - nulls = bitvec.And(bitvec.Not(bits), nulls) - return vector.NewBool(bits, nulls) + return vector.Or(toBool(lhs), toBool(rhs)) } func (o *Or) orError(err, vec vector.Any) vector.Any { diff --git a/vector/bool.go b/vector/bool.go index 284c1a6b1..d3cf7c806 100644 --- a/vector/bool.go +++ b/vector/bool.go @@ -51,11 +51,15 @@ func (b *Bool) Serialize(builder *scode.Builder, slot uint32) { } } -// Or is a simple case of logical-or where we don't care about nulls in -// the input (presuming the corresponding bits to be false) and we return -// the or'd result as a boolean vector without nulls. func Or(a, b *Bool) *Bool { - return NewBool(bitvec.Or(a.Bits, b.Bits), bitvec.Zero) + bits := bitvec.Or(a.Bits, b.Bits) + if a.Nulls.IsZero() && b.Nulls.IsZero() { + // Fast path involves no nulls. + return NewBool(bits, bitvec.Zero) + } + nulls := bitvec.Or(a.Nulls, b.Nulls) + nulls = bitvec.And(bitvec.Not(bits), nulls) + return NewBool(bits, nulls) } // BoolValue returns the value of slot in vec if the value is a Boolean. It