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