Skip to content

Commit

Permalink
apacheGH-37724: [MATLAB] Add arrow.type.StructType MATLAB class (ap…
Browse files Browse the repository at this point in the history
…ache#37749)

### Rationale for this change

In order to add a `arrow.array.StructArray` MATLAB class (apache#37653), we first need to implement the `arrow.type.StructType` MATLAB class.

### What changes are included in this PR?

1. Added a new MATLAB class `arrow.type.StructType`
2. Added convenience constructor function `arrow.struct()`
3. Added `Struct` as a enumeration value to `arrow.type.ID`
4. Added `arrow.type.traits.StructTraits` MATLAB class. Some of its properties, such as `ArrayConstructor` and `ArrayProxyClassName`, are set to `missing` because they require `arrow.array.StructArray` (apache#37653). When that class is added, we can initialize these properties to correct values.

**Example Usage**
```matlab
>> fieldA = arrow.field("A", arrow.int32());
>> fieldB = arrow.field("B", arrow.timestamp(TimeZone="America/New_York"));
>> fieldC = arrow.field("C", arrow.string());
>> structType = arrow.struct(fieldA, fieldB, fieldC)

structType = 

  StructType with properties:

        ID: Struct
    Fields: [1×3 arrow.type.Field]

>> fieldBFromStruct = structType.field(2)

fieldBFromStruct = 

B: timestamp[us, tz=America/New_York]
```

### Are these changes tested?

Yes.

1. Added a new test class called `tStructType.m`
2. Added a new test case to `tTypeDisplay.m`
3. Updated test case in `tID.m`

### Are there any user-facing changes?

Yes. Users can now create an `arrow.type.StructType` object using the new `arrow.struct()` funciton.

### Future Directions

1. apache#37653
* Closes: apache#37724

Authored-by: Sarah Gilmore <[email protected]>
Signed-off-by: Kevin Gurney <[email protected]>
  • Loading branch information
sgilmore10 authored Sep 18, 2023
1 parent 3db6205 commit a7f5ee0
Show file tree
Hide file tree
Showing 17 changed files with 482 additions and 3 deletions.
2 changes: 2 additions & 0 deletions matlab/src/cpp/arrow/matlab/proxy/factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "arrow/matlab/type/proxy/date64_type.h"
#include "arrow/matlab/type/proxy/time32_type.h"
#include "arrow/matlab/type/proxy/time64_type.h"
#include "arrow/matlab/type/proxy/struct_type.h"
#include "arrow/matlab/type/proxy/field.h"
#include "arrow/matlab/io/feather/proxy/writer.h"
#include "arrow/matlab/io/feather/proxy/reader.h"
Expand Down Expand Up @@ -81,6 +82,7 @@ libmexclass::proxy::MakeResult Factory::make_proxy(const ClassName& class_name,
REGISTER_PROXY(arrow.type.proxy.Time64Type , arrow::matlab::type::proxy::Time64Type);
REGISTER_PROXY(arrow.type.proxy.Date32Type , arrow::matlab::type::proxy::Date32Type);
REGISTER_PROXY(arrow.type.proxy.Date64Type , arrow::matlab::type::proxy::Date64Type);
REGISTER_PROXY(arrow.type.proxy.StructType , arrow::matlab::type::proxy::StructType);
REGISTER_PROXY(arrow.io.feather.proxy.Writer , arrow::matlab::io::feather::proxy::Writer);
REGISTER_PROXY(arrow.io.feather.proxy.Reader , arrow::matlab::io::feather::proxy::Reader);

Expand Down
45 changes: 45 additions & 0 deletions matlab/src/cpp/arrow/matlab/type/proxy/struct_type.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#include "arrow/matlab/type/proxy/struct_type.h"
#include "arrow/matlab/type/proxy/field.h"
#include "libmexclass/proxy/ProxyManager.h"

namespace arrow::matlab::type::proxy {

StructType::StructType(std::shared_ptr<arrow::StructType> struct_type) : Type(std::move(struct_type)) {}

libmexclass::proxy::MakeResult StructType::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) {
namespace mda = ::matlab::data;
using StructTypeProxy = arrow::matlab::type::proxy::StructType;

mda::StructArray args = constructor_arguments[0];
const mda::TypedArray<uint64_t> field_proxy_ids_mda = args[0]["FieldProxyIDs"];

std::vector<std::shared_ptr<arrow::Field>> fields;
fields.reserve(field_proxy_ids_mda.getNumberOfElements());
for (const auto proxy_id : field_proxy_ids_mda) {
using namespace libmexclass::proxy;
auto proxy = std::static_pointer_cast<proxy::Field>(ProxyManager::getProxy(proxy_id));
auto field = proxy->unwrap();
fields.push_back(field);
}

auto struct_type = std::static_pointer_cast<arrow::StructType>(arrow::struct_(fields));
return std::make_shared<StructTypeProxy>(std::move(struct_type));
}
}
34 changes: 34 additions & 0 deletions matlab/src/cpp/arrow/matlab/type/proxy/struct_type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#pragma once

#include "arrow/matlab/type/proxy/type.h"

namespace arrow::matlab::type::proxy {

class StructType : public arrow::matlab::type::proxy::Type {

public:
StructType(std::shared_ptr<arrow::StructType> struct_type);

~StructType() {}

static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments);
};

}
3 changes: 3 additions & 0 deletions matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "arrow/matlab/type/proxy/date32_type.h"
#include "arrow/matlab/type/proxy/date64_type.h"
#include "arrow/matlab/type/proxy/string_type.h"
#include "arrow/matlab/type/proxy/struct_type.h"

namespace arrow::matlab::type::proxy {

Expand Down Expand Up @@ -64,6 +65,8 @@ namespace arrow::matlab::type::proxy {
return std::make_shared<Date64Type>(std::static_pointer_cast<arrow::Date64Type>(type));
case ID::STRING:
return std::make_shared<StringType>(std::static_pointer_cast<arrow::StringType>(type));
case ID::STRUCT:
return std::make_shared<StructType>(std::static_pointer_cast<arrow::StructType>(type));
default:
return arrow::Status::NotImplemented("Unsupported DataType: " + type->ToString());
}
Expand Down
36 changes: 36 additions & 0 deletions matlab/src/matlab/+arrow/+type/+traits/StructTraits.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
% Licensed to the Apache Software Foundation (ASF) under one or more
% contributor license agreements. See the NOTICE file distributed with
% this work for additional information regarding copyright ownership.
% The ASF licenses this file to you under the Apache License, Version
% 2.0 (the "License"); you may not use this file except in compliance
% with the License. You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
% implied. See the License for the specific language governing
% permissions and limitations under the License.

classdef StructTraits < arrow.type.traits.TypeTraits

properties (Constant)
% TODO: When arrow.array.StructArray is implemented, set these
% properties appropriately
ArrayConstructor = missing
ArrayClassName = missing
ArrayProxyClassName = missing
ArrayStaticConstructor = missing

TypeConstructor = @arrow.type.StructType
TypeClassName = "arrow.type.StructType"
TypeProxyClassName = "arrow.type.proxy.StructType"

% TODO: When arrow.array.StructArray is implemented, set these
% properties appropriately
MatlabConstructor = missing
MatlabClassName = missing
end

end
2 changes: 2 additions & 0 deletions matlab/src/matlab/+arrow/+type/+traits/traits.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
typeTraits = Date32Traits();
case ID.Date64
typeTraits = Date64Traits();
case ID.Struct
typeTraits = StructTraits();
otherwise
error("arrow:type:traits:UnsupportedArrowTypeID", "Unsupported Arrow type ID: " + type);
end
Expand Down
6 changes: 6 additions & 0 deletions matlab/src/matlab/+arrow/+type/ID.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,11 @@
Timestamp (18)
Time32 (19)
Time64 (20)
% IntervalMonths (21)
% IntervalDayTime (22)
% Decimal128 (23)
% Decimal256 (24)
% List (25)
Struct (26)
end
end
46 changes: 46 additions & 0 deletions matlab/src/matlab/+arrow/+type/StructType.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
% Licensed to the Apache Software Foundation (ASF) under one or more
% contributor license agreements. See the NOTICE file distributed with
% this work for additional information regarding copyright ownership.
% The ASF licenses this file to you under the Apache License, Version
% 2.0 (the "License"); you may not use this file except in compliance
% with the License. You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
% implied. See the License for the specific language governing
% permissions and limitations under the License.

classdef StructType < arrow.type.Type

methods
function obj = StructType(proxy)
arguments
proxy(1, 1) libmexclass.proxy.Proxy {validate(proxy, "arrow.type.proxy.StructType")}
end
import arrow.internal.proxy.validate
[email protected](proxy);
end
end

methods(Access = protected)
function groups = getDisplayPropertyGroups(obj)
targets = ["ID", "Fields"];
groups = matlab.mixin.util.PropertyGroup(targets);
end
end

methods (Hidden)
% TODO: Consider using a mixin approach to add this behavior. For
% example, ChunkedArray's toMATLAB method could check if its
% Type inherits from a mixin called "Preallocateable" (or something
% more descriptive). If so, we can call preallocateMATLABArray
% in the toMATLAB method.
function preallocateMATLABArray(~)
error("arrow:type:UnsupportedFunction", ...
"preallocateMATLABArray is not supported for StructType");
end
end
end
2 changes: 1 addition & 1 deletion matlab/src/matlab/+arrow/+type/Type.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
for ii = 1:numFields
fields{ii} = obj.field(ii);
end
fields = horzcat(fields);
fields = horzcat(fields{:});
end
end
end
Expand Down
43 changes: 43 additions & 0 deletions matlab/src/matlab/+arrow/struct.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
%STRUCT Constructs an arrow.type.StructType object

% Licensed to the Apache Software Foundation (ASF) under one or more
% contributor license agreements. See the NOTICE file distributed with
% this work for additional information regarding copyright ownership.
% The ASF licenses this file to you under the Apache License, Version
% 2.0 (the "License"); you may not use this file except in compliance
% with the License. You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
% implied. See the License for the specific language governing
% permissions and limitations under the License.

function type = struct(fields)
arguments(Repeating)
fields(1, :) arrow.type.Field {mustBeNonempty}
end

% Must have at least one Field in a Struct
if isempty(fields)
error("arrow:struct:TooFewInputs", ...
"Must supply at least one arrow.type.Field");
end

fields = horzcat(fields{:});

% Extract the corresponding Proxy IDs from each of the
% supplied arrow.type.Field objects.
numFields = numel(fields);
fieldProxyIDs = zeros(1, numFields, "uint64");
for ii = 1:numFields
fieldProxyIDs(ii) = fields(ii).Proxy.ID;
end

% Construct an Arrow Field Proxy in C++ from the supplied Field Proxy IDs.
args = struct(FieldProxyIDs=fieldProxyIDs);
proxy = arrow.internal.proxy.create("arrow.type.proxy.StructType", args);
type = arrow.type.StructType(proxy);
end
1 change: 1 addition & 0 deletions matlab/test/arrow/type/tField.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ function TestSupportedTypes(testCase)
arrow.float64, ...
arrow.string, ...
arrow.timestamp, ...
arrow.struct(arrow.field("A", arrow.float32()))
};
for ii = 1:numel(supportedTypes)
supportedType = supportedTypes{ii};
Expand Down
3 changes: 2 additions & 1 deletion matlab/test/arrow/type/tID.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ function CastToUInt64(testCase)
ID.Date64, 17, ...
ID.Timestamp, 18, ...
ID.Time32, 19, ...
ID.Time64, 20 ...
ID.Time64, 20, ...
ID.Struct, 26 ...
);

enumValues = typeIDs.keys();
Expand Down
Loading

0 comments on commit a7f5ee0

Please sign in to comment.