Serialization is accomplished by converting expressions to KeyValueMetadata and storing this in the schema of a RecordBatch. Embedded arrays and scalars are stored in its columns. Finally, the RecordBatch is written to an IPC file.
| 1502 | // this in the schema of a RecordBatch. Embedded arrays and scalars are stored in its |
| 1503 | // columns. Finally, the RecordBatch is written to an IPC file. |
| 1504 | Result<std::shared_ptr<Buffer>> Serialize(const Expression& expr) { |
| 1505 | #ifdef ARROW_IPC |
| 1506 | struct { |
| 1507 | std::shared_ptr<KeyValueMetadata> metadata_ = std::make_shared<KeyValueMetadata>(); |
| 1508 | ArrayVector columns_; |
| 1509 | |
| 1510 | Result<std::string> AddScalar(const Scalar& scalar) { |
| 1511 | auto ret = columns_.size(); |
| 1512 | ARROW_ASSIGN_OR_RAISE(auto array, MakeArrayFromScalar(scalar, 1)); |
| 1513 | columns_.push_back(std::move(array)); |
| 1514 | return ToChars(ret); |
| 1515 | } |
| 1516 | |
| 1517 | Status VisitFieldRef(const FieldRef& ref) { |
| 1518 | if (ref.nested_refs()) { |
| 1519 | metadata_->Append("nested_field_ref", ToChars(ref.nested_refs()->size())); |
| 1520 | for (const auto& child : *ref.nested_refs()) { |
| 1521 | RETURN_NOT_OK(VisitFieldRef(child)); |
| 1522 | } |
| 1523 | return Status::OK(); |
| 1524 | } |
| 1525 | if (!ref.name()) { |
| 1526 | return Status::NotImplemented("Serialization of non-name field_refs"); |
| 1527 | } |
| 1528 | metadata_->Append("field_ref", *ref.name()); |
| 1529 | return Status::OK(); |
| 1530 | } |
| 1531 | |
| 1532 | Status Visit(const Expression& expr) { |
| 1533 | if (auto lit = expr.literal()) { |
| 1534 | if (!lit->is_scalar()) { |
| 1535 | return Status::NotImplemented("Serialization of non-scalar literals"); |
| 1536 | } |
| 1537 | ARROW_ASSIGN_OR_RAISE(auto value, AddScalar(*lit->scalar())); |
| 1538 | metadata_->Append("literal", std::move(value)); |
| 1539 | return Status::OK(); |
| 1540 | } |
| 1541 | |
| 1542 | if (auto ref = expr.field_ref()) { |
| 1543 | return VisitFieldRef(*ref); |
| 1544 | } |
| 1545 | |
| 1546 | auto call = CallNotNull(expr); |
| 1547 | metadata_->Append("call", call->function_name); |
| 1548 | |
| 1549 | for (const auto& argument : call->arguments) { |
| 1550 | RETURN_NOT_OK(Visit(argument)); |
| 1551 | } |
| 1552 | |
| 1553 | if (call->options) { |
| 1554 | ARROW_ASSIGN_OR_RAISE(auto options_scalar, |
| 1555 | internal::FunctionOptionsToStructScalar(*call->options)); |
| 1556 | ARROW_ASSIGN_OR_RAISE(auto value, AddScalar(*options_scalar)); |
| 1557 | metadata_->Append("options", std::move(value)); |
| 1558 | } |
| 1559 | |
| 1560 | metadata_->Append("end", call->function_name); |
| 1561 | return Status::OK(); |
nothing calls this directly
no test coverage detected