lidavidm commented on code in PR #44587:
URL: https://github.com/apache/arrow/pull/44587#discussion_r1842272882
##########
cpp/src/arrow/compute/kernels/scalar_cast_nested.cc:
##########
@@ -348,25 +349,47 @@ struct CastStruct {
std::vector<int> fields_to_select(out_field_count, -1);
- int out_field_index = 0;
- for (int in_field_index = 0;
- in_field_index < in_field_count && out_field_index < out_field_count;
- ++in_field_index) {
- const auto& in_field = in_type.field(in_field_index);
+ std::set<std::string> all_in_field_names;
+ for (int in_field_index = 0; in_field_index < in_field_count;
++in_field_index) {
+ all_in_field_names.insert(in_type.field(in_field_index)->name());
+ }
+
+ for (int in_field_index = 0, out_field_index = 0;
+ out_field_index < out_field_count;) {
const auto& out_field = out_type.field(out_field_index);
- if (in_field->name() == out_field->name()) {
- if (in_field->nullable() && !out_field->nullable()) {
- return Status::TypeError("cannot cast nullable field to non-nullable
field: ",
- in_type.ToString(), " ",
out_type.ToString());
+ if (in_field_index < in_field_count) {
+ const auto& in_field = in_type.field(in_field_index);
+ // If there are more in_fields check if they match the out_field.
+ if (in_field->name() == out_field->name()) {
+ if (in_field->nullable() && !out_field->nullable()) {
+ return Status::TypeError("cannot cast nullable field to
non-nullable field: ",
+ in_type.ToString(), " ",
out_type.ToString());
+ }
+ // Found matching in_field and out_field.
+ fields_to_select[out_field_index++] = in_field_index;
+ // Using the same in_field for multiple out_fields is not allowed.
+ in_field_index++;
+ continue;
}
- fields_to_select[out_field_index++] = in_field_index;
}
- }
-
- if (out_field_index < out_field_count) {
- return Status::TypeError(
- "struct fields don't match or are in the wrong order: Input fields:
",
- in_type.ToString(), " output fields: ", out_type.ToString());
+ if (all_in_field_names.count(out_field->name()) == 0 &&
out_field->nullable()) {
+ // Didn't match current in_field, but we can fill with null.
+ // Filling with null is only acceptable on nuallable fields when there
+ // is definitely no in_field with matching name.
+
+ // -2 is a sentinel value indicating fill with null.
+ fields_to_select[out_field_index++] = -2;
Review Comment:
It can be placed inside the method definition itself!
--
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]