1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17
18 #include <memory>
19 #include <string>
20
21 #include <gtest/gtest.h>
22
23 #include "arrow/array/array_base.h"
24 #include "arrow/chunked_array.h"
25 #include "arrow/datum.h"
26 #include "arrow/scalar.h"
27 #include "arrow/table.h"
28 #include "arrow/testing/gtest_common.h"
29 #include "arrow/testing/gtest_util.h"
30 #include "arrow/type_fwd.h"
31 #include "arrow/util/checked_cast.h"
32
33 namespace arrow {
34
35 class BinaryArray;
36 class RecordBatch;
37
38 using internal::checked_cast;
39
40 // ----------------------------------------------------------------------
41 // Datum
42
43 template <typename T>
CheckImplicitConstructor(Datum::Kind expected_kind)44 void CheckImplicitConstructor(Datum::Kind expected_kind) {
45 std::shared_ptr<T> value;
46 Datum datum = value;
47 ASSERT_EQ(expected_kind, datum.kind());
48 }
49
TEST(Datum,ImplicitConstructors)50 TEST(Datum, ImplicitConstructors) {
51 CheckImplicitConstructor<Scalar>(Datum::SCALAR);
52
53 CheckImplicitConstructor<Array>(Datum::ARRAY);
54
55 // Instantiate from array subclass
56 CheckImplicitConstructor<BinaryArray>(Datum::ARRAY);
57
58 CheckImplicitConstructor<ChunkedArray>(Datum::CHUNKED_ARRAY);
59 CheckImplicitConstructor<RecordBatch>(Datum::RECORD_BATCH);
60
61 CheckImplicitConstructor<Table>(Datum::TABLE);
62 }
63
TEST(Datum,Constructors)64 TEST(Datum, Constructors) {
65 Datum val(std::make_shared<Int64Scalar>(1));
66 ASSERT_EQ(ValueDescr::SCALAR, val.shape());
67 AssertTypeEqual(*int64(), *val.type());
68 ASSERT_TRUE(val.is_scalar());
69 ASSERT_FALSE(val.is_array());
70 ASSERT_EQ(1, val.length());
71
72 const Int64Scalar& val_as_i64 = checked_cast<const Int64Scalar&>(*val.scalar());
73 const Int64Scalar& val_as_i64_2 = val.scalar_as<Int64Scalar>();
74 ASSERT_EQ(1, val_as_i64.value);
75 ASSERT_EQ(1, val_as_i64_2.value);
76
77 auto arr = ArrayFromJSON(int64(), "[1, 2, 3, 4]");
78 auto sel_indices = ArrayFromJSON(int32(), "[0, 3]");
79
80 Datum val2(arr);
81 ASSERT_EQ(Datum::ARRAY, val2.kind());
82 ASSERT_EQ(ValueDescr::ARRAY, val2.shape());
83 AssertTypeEqual(*int64(), *val2.type());
84 AssertArraysEqual(*arr, *val2.make_array());
85 ASSERT_TRUE(val2.is_array());
86 ASSERT_FALSE(val2.is_scalar());
87 ASSERT_EQ(arr->length(), val2.length());
88
89 auto Check = [&](const Datum& v) { AssertArraysEqual(*arr, *v.make_array()); };
90
91 // Copy constructor
92 Datum val3 = val2;
93 Check(val3);
94
95 // Copy assignment
96 Datum val4;
97 val4 = val2;
98 Check(val4);
99
100 // Move constructor
101 Datum val5 = std::move(val2);
102 Check(val5);
103
104 // Move assignment
105 Datum val6;
106 val6 = std::move(val4);
107 Check(val6);
108 }
109
TEST(Datum,NullCount)110 TEST(Datum, NullCount) {
111 Datum val1(std::make_shared<Int8Scalar>(1));
112 ASSERT_EQ(0, val1.null_count());
113
114 Datum val2(MakeNullScalar(int8()));
115 ASSERT_EQ(1, val2.null_count());
116
117 Datum val3(ArrayFromJSON(int8(), "[1, null, null, null]"));
118 ASSERT_EQ(3, val3.null_count());
119 }
120
TEST(Datum,MutableArray)121 TEST(Datum, MutableArray) {
122 auto arr = ArrayFromJSON(int8(), "[1, 2, 3, 4]");
123
124 Datum val(arr);
125
126 val.mutable_array()->length = 0;
127 ASSERT_EQ(0, val.array()->length);
128 }
129
TEST(Datum,ToString)130 TEST(Datum, ToString) {
131 auto arr = ArrayFromJSON(int8(), "[1, 2, 3, 4]");
132
133 Datum v1(arr);
134 Datum v2(std::make_shared<Int8Scalar>(1));
135
136 std::vector<Datum> vec1 = {v1};
137 Datum v3(vec1);
138
139 std::vector<Datum> vec2 = {v1, v2};
140 Datum v4(vec2);
141
142 ASSERT_EQ("Array", v1.ToString());
143 ASSERT_EQ("Scalar", v2.ToString());
144 ASSERT_EQ("Collection(Array)", v3.ToString());
145 ASSERT_EQ("Collection(Array, Scalar)", v4.ToString());
146 }
147
TEST(ValueDescr,Basics)148 TEST(ValueDescr, Basics) {
149 ValueDescr d1(utf8(), ValueDescr::SCALAR);
150 ValueDescr d2 = ValueDescr::Any(utf8());
151 ValueDescr d3 = ValueDescr::Scalar(utf8());
152 ValueDescr d4 = ValueDescr::Array(utf8());
153
154 ASSERT_EQ(ValueDescr::SCALAR, d1.shape);
155 AssertTypeEqual(*utf8(), *d1.type);
156 ASSERT_EQ(ValueDescr::Scalar(utf8()), d1);
157
158 ASSERT_EQ(ValueDescr::ANY, d2.shape);
159 AssertTypeEqual(*utf8(), *d2.type);
160 ASSERT_EQ(ValueDescr::Any(utf8()), d2);
161 ASSERT_NE(ValueDescr::Any(int32()), d2);
162
163 ASSERT_EQ(ValueDescr::SCALAR, d3.shape);
164 ASSERT_EQ(ValueDescr::ARRAY, d4.shape);
165
166 ASSERT_EQ("scalar[string]", d1.ToString());
167 ASSERT_EQ("any[string]", d2.ToString());
168 ASSERT_EQ("scalar[string]", d3.ToString());
169 ASSERT_EQ("array[string]", d4.ToString());
170 }
171
172 } // namespace arrow
173