pitrou commented on code in PR #50269:
URL: https://github.com/apache/arrow/pull/50269#discussion_r3628339485


##########
cpp/src/arrow/compute/kernels/scalar_validity.cc:
##########
@@ -101,45 +80,74 @@ static void SetNanBits(const ArraySpan& arr, uint8_t* 
out_bitmap, int64_t out_of
   }
 }
 
-Status IsNullExec(KernelContext* ctx, const ExecSpan& batch, ExecResult* out) {
-  const ArraySpan& arr = batch[0].array;
-  ArraySpan* out_span = out->array_span_mutable();
-  if (arr.type->id() == Type::NA) {
-    bit_util::SetBitsTo(out_span->buffers[1].data, out_span->offset, 
out_span->length,
-                        true);
-    return Status::OK();
-  }
-
-  const auto& options = NanOptionsState::Get(ctx);
-  uint8_t* out_bitmap = out_span->buffers[1].data;
-  if (arr.GetNullCount() > 0) {
-    // Input has nulls => output is the inverted null (validity) bitmap.
-    InvertBitmap(arr.buffers[0].data, arr.offset, arr.length, out_bitmap,
-                 out_span->offset);
+// `nan_is_null` can only be true for the is_null kernel since the is_valid and
+// true_unless_null kernels currently do not take `NullOptions`
+Status SetLogicalNullBits(const ArraySpan& span, uint8_t* out_bitmap, int64_t 
out_offset,
+                          bool set_on_null, bool nan_is_null) {
+  const Type::type t = span.type->id();
+  if (t == Type::NA) {
+    // Input is all nulls, so all output bits are the same.
+    bit_util::SetBitsTo(out_bitmap, out_offset, span.length, set_on_null);
+  } else if (t == Type::SPARSE_UNION) {
+    union_util::SetLogicalNullBitsSparse(span, out_bitmap, out_offset, 
set_on_null);
+  } else if (t == Type::DENSE_UNION) {
+    union_util::SetLogicalNullBitsDense(span, out_bitmap, out_offset, 
set_on_null);
+  } else if (t == Type::RUN_END_ENCODED) {
+    ree_util::SetLogicalNullBits(span, out_bitmap, out_offset, set_on_null);
+  } else if (t == Type::DICTIONARY) {
+    dict_util::SetLogicalNullBits(span, out_bitmap, out_offset, set_on_null);

Review Comment:
   I note we're not propagating down `nan_is_null` here. Should we open an 
issue for it and leave a TODO here?



##########
cpp/src/arrow/util/dict_util.cc:
##########
@@ -78,5 +116,54 @@ int64_t LogicalNullCount(const ArraySpan& span) {
       return LogicalNullCount<Int64Type>(span);
   }
 }
+
+void SetLogicalNullBits(const ArraySpan& span, uint8_t* out_bitmap, int64_t 
out_offset,
+                        bool set_on_null) {
+  if (span.dictionary().GetNullCount() == 0) {
+    // No nulls in dictionary, so a value is a logical null if and only if
+    // its index is null
+    if (span.GetNullCount() == 0) {
+      // No null indices either (and possibly no validity bitmap at all), so
+      // there are no logical nulls
+      bit_util::SetBitsTo(out_bitmap, out_offset, span.length, !set_on_null);
+    } else if (set_on_null) {
+      internal::InvertBitmap(span.buffers[0].data, span.offset, span.length, 
out_bitmap,
+                             out_offset);
+    } else {
+      internal::CopyBitmap(span.buffers[0].data, span.offset, span.length, 
out_bitmap,
+                           out_offset);
+    }
+    return;
+  }
+
+  const auto& dict_array_type = internal::checked_cast<const 
DictionaryType&>(*span.type);
+  switch (dict_array_type.index_type()->id()) {

Review Comment:
   I've opened https://github.com/apache/arrow/issues/50595 to make such 
snippets easier to write.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to