1818 */
1919
2020#include " graphar/high-level/vertices_builder.h"
21+ #include < any>
22+ #include < iterator>
23+ #include < vector>
2124#include " graphar/convert_to_arrow_type.h"
25+ #include " graphar/fwd.h"
2226#include " graphar/graph_info.h"
27+ #include " graphar/label.h"
28+ #include " graphar/status.h"
2329
2430namespace graphar ::builder {
2531
@@ -66,59 +72,62 @@ Status VerticesBuilder::validate(const Vertex& v, IdType index,
6672 bool invalid_type = false ;
6773 switch (type->id ()) {
6874 case Type::BOOL:
69- if (property. second . type () !=
70- typeid ( typename TypeToArrowType<Type::BOOL>::CType)) {
71- invalid_type = true ;
72- }
75+ GAR_RETURN_NOT_OK (
76+ v. ValidatePropertyType < typename TypeToArrowType<Type::BOOL>::CType>(
77+ property. first ,
78+ vertex_info_-> GetPropertyCardinality (property. first ). value ()));
7379 break ;
7480 case Type::INT32:
75- if (property. second . type () !=
76- typeid ( typename TypeToArrowType<Type::INT32>::CType)) {
77- invalid_type = true ;
78- }
81+ GAR_RETURN_NOT_OK (v. ValidatePropertyType <
82+ typename TypeToArrowType<Type::INT32>::CType>(
83+ property. first ,
84+ vertex_info_-> GetPropertyCardinality (property. first ). value ()));
7985 break ;
8086 case Type::INT64:
81- if (property. second . type () !=
82- typeid ( typename TypeToArrowType<Type::INT64>::CType)) {
83- invalid_type = true ;
84- }
87+ GAR_RETURN_NOT_OK (v. ValidatePropertyType <
88+ typename TypeToArrowType<Type::INT64>::CType>(
89+ property. first ,
90+ vertex_info_-> GetPropertyCardinality (property. first ). value ()));
8591 break ;
8692 case Type::FLOAT:
87- if (property. second . type () !=
88- typeid ( typename TypeToArrowType<Type::FLOAT>::CType)) {
89- invalid_type = true ;
90- }
93+ GAR_RETURN_NOT_OK (v. ValidatePropertyType <
94+ typename TypeToArrowType<Type::FLOAT>::CType>(
95+ property. first ,
96+ vertex_info_-> GetPropertyCardinality (property. first ). value ()));
9197 break ;
9298 case Type::DOUBLE:
93- if (property. second . type () !=
94- typeid ( typename TypeToArrowType<Type::DOUBLE>::CType)) {
95- invalid_type = true ;
96- }
99+ GAR_RETURN_NOT_OK (v. ValidatePropertyType <
100+ typename TypeToArrowType<Type::DOUBLE>::CType>(
101+ property. first ,
102+ vertex_info_-> GetPropertyCardinality (property. first ). value ()));
97103 break ;
98104 case Type::STRING:
99- if (property. second . type () !=
100- typeid ( typename TypeToArrowType<Type::STRING>::CType)) {
101- invalid_type = true ;
102- }
105+ GAR_RETURN_NOT_OK (v. ValidatePropertyType <
106+ typename TypeToArrowType<Type::STRING>::CType>(
107+ property. first ,
108+ vertex_info_-> GetPropertyCardinality (property. first ). value ()));
103109 break ;
104110 case Type::DATE:
105111 // date is stored as int32_t
106- if (property. second . type () !=
107- typeid ( typename TypeToArrowType<Type::DATE>::CType::c_type)) {
108- invalid_type = true ;
109- }
112+ GAR_RETURN_NOT_OK (v. ValidatePropertyType <
113+ typename TypeToArrowType<Type::DATE>::CType::c_type>(
114+ property. first ,
115+ vertex_info_-> GetPropertyCardinality (property. first ). value ()));
110116 break ;
111117 case Type::TIMESTAMP:
112118 // timestamp is stored as int64_t
113- if (property.second .type () !=
114- typeid (typename TypeToArrowType<Type::TIMESTAMP>::CType::c_type)) {
115- invalid_type = true ;
116- }
119+ GAR_RETURN_NOT_OK (
120+ v.ValidatePropertyType <
121+ typename TypeToArrowType<Type::TIMESTAMP>::CType::c_type>(
122+ property.first ,
123+ vertex_info_->GetPropertyCardinality (property.first ).value ()));
117124 break ;
118125 default :
119126 return Status::TypeError (" Unsupported property type." );
120127 }
121- if (invalid_type) {
128+ if (invalid_type &&
129+ Cardinality::SINGLE ==
130+ vertex_info_->GetPropertyCardinality (property.first ).value ()) {
122131 return Status::TypeError (
123132 " Invalid data type for property " , property.first + " , defined as " ,
124133 type->ToTypeName (), " , but got " , property.second .type ().name ());
@@ -134,16 +143,41 @@ Status VerticesBuilder::tryToAppend(
134143 std::shared_ptr<arrow::Array>& array) { // NOLINT
135144 using CType = typename TypeToArrowType<type>::CType;
136145 arrow::MemoryPool* pool = arrow::default_memory_pool ();
137- typename TypeToArrowType<type>::BuilderType builder (pool);
138- for (auto & v : vertices_) {
139- if (v.Empty () || !v.ContainProperty (property_name)) {
140- RETURN_NOT_ARROW_OK (builder.AppendNull ());
141- } else {
142- RETURN_NOT_ARROW_OK (
143- builder.Append (std::any_cast<CType>(v.GetProperty (property_name))));
146+ auto builder =
147+ std::make_shared<typename TypeToArrowType<type>::BuilderType>(pool);
148+ auto cardinality =
149+ vertex_info_->GetPropertyCardinality (property_name).value ();
150+ if (cardinality != Cardinality::SINGLE) {
151+ arrow::ListBuilder list_builder (pool, builder);
152+ for (auto & v : vertices_) {
153+ RETURN_NOT_ARROW_OK (list_builder.Append ());
154+ if (v.Empty () || !v.ContainProperty (property_name)) {
155+ RETURN_NOT_ARROW_OK (builder->AppendNull ());
156+ } else {
157+ if (!v.IsMultiProperty (property_name)) {
158+ RETURN_NOT_ARROW_OK (builder->Append (
159+ std::any_cast<CType>(v.GetProperty (property_name))));
160+ } else {
161+ auto property_value_list = std::any_cast<std::vector<std::any>>(
162+ v.GetProperty (property_name));
163+ for (auto & value : property_value_list) {
164+ RETURN_NOT_ARROW_OK (builder->Append (std::any_cast<CType>(value)));
165+ }
166+ }
167+ }
168+ }
169+ array = list_builder.Finish ().ValueOrDie ();
170+ } else {
171+ for (auto & v : vertices_) {
172+ if (v.Empty () || !v.ContainProperty (property_name)) {
173+ RETURN_NOT_ARROW_OK (builder->AppendNull ());
174+ } else {
175+ RETURN_NOT_ARROW_OK (builder->Append (
176+ std::any_cast<CType>(v.GetProperty (property_name))));
177+ }
144178 }
179+ array = builder->Finish ().ValueOrDie ();
145180 }
146- array = builder.Finish ().ValueOrDie ();
147181 return Status::OK ();
148182}
149183
@@ -219,11 +253,18 @@ Result<std::shared_ptr<arrow::Table>> VerticesBuilder::convertToTable() {
219253 for (auto & property_group : property_groups) {
220254 for (auto & property : property_group->GetProperties ()) {
221255 // add a column to schema
222- schema_vector.push_back (arrow::field (
223- property.name , DataType::DataTypeToArrowDataType (property.type )));
256+ if (vertex_info_->GetPropertyCardinality (property.name ).value () !=
257+ Cardinality::SINGLE) {
258+ schema_vector.push_back (arrow::field (
259+ property.name ,
260+ arrow::list (DataType::DataTypeToArrowDataType (property.type ))));
261+ } else {
262+ schema_vector.push_back (arrow::field (
263+ property.name , DataType::DataTypeToArrowDataType (property.type )));
264+ }
224265 // add a column to data
225266 std::shared_ptr<arrow::Array> array;
226- appendToArray (property.type , property.name , array);
267+ GAR_RETURN_NOT_OK ( appendToArray (property.type , property.name , array) );
227268 arrays.push_back (array);
228269 }
229270 }
0 commit comments