| 102 | } |
| 103 | |
| 104 | Status IsNullExec(KernelContext* ctx, const ExecSpan& batch, ExecResult* out) { |
| 105 | const ArraySpan& arr = batch[0].array; |
| 106 | ArraySpan* out_span = out->array_span_mutable(); |
| 107 | if (arr.type->id() == Type::NA) { |
| 108 | bit_util::SetBitsTo(out_span->buffers[1].data, out_span->offset, out_span->length, |
| 109 | true); |
| 110 | return Status::OK(); |
| 111 | } |
| 112 | |
| 113 | const auto& options = NanOptionsState::Get(ctx); |
| 114 | uint8_t* out_bitmap = out_span->buffers[1].data; |
| 115 | if (arr.GetNullCount() > 0) { |
| 116 | // Input has nulls => output is the inverted null (validity) bitmap. |
| 117 | InvertBitmap(arr.buffers[0].data, arr.offset, arr.length, out_bitmap, |
| 118 | out_span->offset); |
| 119 | } else { |
| 120 | // Input has no nulls => output is entirely false. |
| 121 | bit_util::SetBitsTo(out_bitmap, out_span->offset, out_span->length, false); |
| 122 | } |
| 123 | |
| 124 | if (is_floating(arr.type->id()) && options.nan_is_null) { |
| 125 | switch (arr.type->id()) { |
| 126 | case Type::FLOAT: |
| 127 | SetNanBits<float>(arr, out_bitmap, out_span->offset); |
| 128 | break; |
| 129 | case Type::DOUBLE: |
| 130 | SetNanBits<double>(arr, out_bitmap, out_span->offset); |
| 131 | break; |
| 132 | case Type::HALF_FLOAT: |
| 133 | SetNanBits<uint16_t>(arr, out_bitmap, out_span->offset); |
| 134 | break; |
| 135 | default: |
| 136 | return Status::NotImplemented("NaN detection not implemented for type ", |
| 137 | arr.type->ToString()); |
| 138 | } |
| 139 | } |
| 140 | return Status::OK(); |
| 141 | } |
| 142 | |
| 143 | struct IsNanOperator { |
| 144 | template <typename OutType, typename InType> |
nothing calls this directly
no test coverage detected