dhruv9vats commented on a change in pull request #12162:
URL: https://github.com/apache/arrow/pull/12162#discussion_r795901860



##########
File path: cpp/src/arrow/compute/kernels/scalar_nested.cc
##########
@@ -428,6 +429,276 @@ const FunctionDoc make_struct_doc{"Wrap Arrays into a 
StructArray",
                                    "specified through MakeStructOptions."),
                                   {"*args"},
                                   "MakeStructOptions"};
+template <typename KeyType>
+struct MapArrayLookupFunctor {
+  static Result<int64_t> GetOneMatchingIndex(const Array& keys,
+                                             const Scalar& query_key_scalar,
+                                             const bool* from_back) {
+    int64_t match_index = -1;
+    RETURN_NOT_OK(
+        FindMatchingIndices(keys, query_key_scalar, [&](int64_t index) -> 
Status {
+          match_index = index;
+          if (*from_back) {
+            return Status::OK();
+          } else {
+            return Status::Cancelled("Found key match for FIRST");
+          }
+        }));
+
+    return match_index;
+  }
+
+  static Status BuildItemsArray(const Array& keys, const Array& items,
+                                const Scalar& query_key_scalar,
+                                bool* found_at_least_one_key, ArrayBuilder* 
builder) {
+    RETURN_NOT_OK(
+        FindMatchingIndices(keys, query_key_scalar, [&](int64_t index) -> 
Status {
+          *found_at_least_one_key = true;
+          RETURN_NOT_OK(builder->AppendArraySlice(*items.data(), index, 1));
+          return Status::OK();
+        }));
+    return Status::OK();
+  }
+
+  template <typename FoundItem>
+  static Status FindMatchingIndices(const Array& keys, const Scalar& 
query_key_scalar,
+                                    FoundItem callback) {
+    const auto query_key = UnboxScalar<KeyType>::Unbox(query_key_scalar);
+    int64_t index = 0;
+    Status status = VisitArrayValuesInline<KeyType>(
+        *keys.data(),
+        [&](decltype(query_key) key) -> Status {
+          if (key == query_key) {
+            return callback(index++);
+          }
+          ++index;
+          return Status::OK();
+        },
+        [&]() -> Status {
+          ++index;
+          return Status::OK();
+        });
+    if (!status.ok() && !status.IsCancelled()) {
+      return status;
+    }
+    return Status::OK();
+  }
+
+  static Status ExecMapArray(KernelContext* ctx, const ExecBatch& batch, 
Datum* out) {
+    const auto& options = OptionsWrapper<MapArrayLookupOptions>::Get(ctx);
+    const auto& query_key = options.query_key;
+    const auto& occurrence = options.occurrence;
+    const MapArray map_array(batch[0].array());
+
+    std::unique_ptr<ArrayBuilder> builder;
+    if (occurrence == MapArrayLookupOptions::Occurrence::ALL) {
+      RETURN_NOT_OK(MakeBuilder(ctx->memory_pool(),
+                                list(map_array.map_type()->item_type()), 
&builder));
+      auto list_builder = checked_cast<ListBuilder*>(builder.get());
+      auto value_builder = list_builder->value_builder();
+
+      for (int64_t map_array_idx = 0; map_array_idx < map_array.length();
+           ++map_array_idx) {
+        if (!map_array.IsValid(map_array_idx)) {
+          RETURN_NOT_OK(list_builder->AppendNull());
+          continue;
+        }
+
+        auto map = map_array.value_slice(map_array_idx);
+        auto keys = checked_cast<const StructArray&>(*map).field(0);
+        auto items = checked_cast<const StructArray&>(*map).field(1);
+        bool found_at_least_one_key = false;
+        RETURN_NOT_OK(
+            FindMatchingIndices(*keys, *query_key, [&](int64_t index) -> 
Status {
+              if (!found_at_least_one_key) 
RETURN_NOT_OK(list_builder->Append(true));
+              found_at_least_one_key = true;
+              RETURN_NOT_OK(value_builder->AppendArraySlice(*items->data(), 
index, 1));
+              return Status::OK();
+            }));

Review comment:
       This needs both the `list_builder` and the `value_builder`, so haven't 
added this to the helper `BuildItemsArray` above as it'll take away from its 
simplicity. Thus, the `BuildItemsArray` could be inlined if need be as it's 
only being used in the Scalar case now.




-- 
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: github-unsubscr...@arrow.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to