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/datum.h"
24 #include "arrow/scalar.h"
25 #include "arrow/testing/gtest_common.h"
26 #include "arrow/testing/gtest_util.h"
27 #include "arrow/type_fwd.h"
28 #include "arrow/util/checked_cast.h"
29 
30 namespace arrow {
31 
32 class ChunkedArray;
33 class RecordBatch;
34 class Table;
35 
36 using internal::checked_cast;
37 
38 // ----------------------------------------------------------------------
39 // Datum
40 
41 template <typename T>
CheckImplicitConstructor(Datum::Kind expected_kind)42 void CheckImplicitConstructor(Datum::Kind expected_kind) {
43   std::shared_ptr<T> value;
44   Datum datum = value;
45   ASSERT_EQ(expected_kind, datum.kind());
46 }
47 
TEST(Datum,ImplicitConstructors)48 TEST(Datum, ImplicitConstructors) {
49   CheckImplicitConstructor<Scalar>(Datum::SCALAR);
50 
51   CheckImplicitConstructor<Array>(Datum::ARRAY);
52 
53   // Instantiate from array subclass
54   CheckImplicitConstructor<BinaryArray>(Datum::ARRAY);
55 
56   CheckImplicitConstructor<ChunkedArray>(Datum::CHUNKED_ARRAY);
57   CheckImplicitConstructor<RecordBatch>(Datum::RECORD_BATCH);
58 
59   CheckImplicitConstructor<Table>(Datum::TABLE);
60 }
61 
TEST(Datum,Constructors)62 TEST(Datum, Constructors) {
63   Datum val(std::make_shared<Int64Scalar>(1));
64   ASSERT_EQ(ValueDescr::SCALAR, val.shape());
65   AssertTypeEqual(*int64(), *val.type());
66   ASSERT_TRUE(val.is_scalar());
67   ASSERT_FALSE(val.is_array());
68   ASSERT_EQ(1, val.length());
69 
70   const Int64Scalar& val_as_i64 = checked_cast<const Int64Scalar&>(*val.scalar());
71   const Int64Scalar& val_as_i64_2 = val.scalar_as<Int64Scalar>();
72   ASSERT_EQ(1, val_as_i64.value);
73   ASSERT_EQ(1, val_as_i64_2.value);
74 
75   auto arr = ArrayFromJSON(int64(), "[1, 2, 3, 4]");
76   auto sel_indices = ArrayFromJSON(int32(), "[0, 3]");
77 
78   Datum val2(arr);
79   ASSERT_EQ(Datum::ARRAY, val2.kind());
80   ASSERT_EQ(ValueDescr::ARRAY, val2.shape());
81   AssertTypeEqual(*int64(), *val2.type());
82   AssertArraysEqual(*arr, *val2.make_array());
83   ASSERT_TRUE(val2.is_array());
84   ASSERT_FALSE(val2.is_scalar());
85   ASSERT_EQ(arr->length(), val2.length());
86 
87   auto Check = [&](const Datum& v) { AssertArraysEqual(*arr, *v.make_array()); };
88 
89   // Copy constructor
90   Datum val3 = val2;
91   Check(val3);
92 
93   // Copy assignment
94   Datum val4;
95   val4 = val2;
96   Check(val4);
97 
98   // Move constructor
99   Datum val5 = std::move(val2);
100   Check(val5);
101 
102   // Move assignment
103   Datum val6;
104   val6 = std::move(val4);
105   Check(val6);
106 }
107 
TEST(Datum,NullCount)108 TEST(Datum, NullCount) {
109   Datum val1(std::make_shared<Int8Scalar>(1));
110   ASSERT_EQ(0, val1.null_count());
111 
112   Datum val2(MakeNullScalar(int8()));
113   ASSERT_EQ(1, val2.null_count());
114 
115   Datum val3(ArrayFromJSON(int8(), "[1, null, null, null]"));
116   ASSERT_EQ(3, val3.null_count());
117 }
118 
TEST(Datum,MutableArray)119 TEST(Datum, MutableArray) {
120   auto arr = ArrayFromJSON(int8(), "[1, 2, 3, 4]");
121 
122   Datum val(arr);
123 
124   val.mutable_array()->length = 0;
125   ASSERT_EQ(0, val.array()->length);
126 }
127 
TEST(Datum,ToString)128 TEST(Datum, ToString) {
129   auto arr = ArrayFromJSON(int8(), "[1, 2, 3, 4]");
130 
131   Datum v1(arr);
132   Datum v2(std::make_shared<Int8Scalar>(1));
133   ASSERT_EQ("Array", v1.ToString());
134   ASSERT_EQ("Scalar", v2.ToString());
135 }
136 
TEST(ValueDescr,Basics)137 TEST(ValueDescr, Basics) {
138   ValueDescr d1(utf8(), ValueDescr::SCALAR);
139   ValueDescr d2 = ValueDescr::Any(utf8());
140   ValueDescr d3 = ValueDescr::Scalar(utf8());
141   ValueDescr d4 = ValueDescr::Array(utf8());
142 
143   ASSERT_EQ(ValueDescr::SCALAR, d1.shape);
144   AssertTypeEqual(*utf8(), *d1.type);
145   ASSERT_EQ(ValueDescr::Scalar(utf8()), d1);
146 
147   ASSERT_EQ(ValueDescr::ANY, d2.shape);
148   AssertTypeEqual(*utf8(), *d2.type);
149   ASSERT_EQ(ValueDescr::Any(utf8()), d2);
150   ASSERT_NE(ValueDescr::Any(int32()), d2);
151 
152   ASSERT_EQ(ValueDescr::SCALAR, d3.shape);
153   ASSERT_EQ(ValueDescr::ARRAY, d4.shape);
154 
155   ASSERT_EQ("scalar[string]", d1.ToString());
156   ASSERT_EQ("any[string]", d2.ToString());
157   ASSERT_EQ("scalar[string]", d3.ToString());
158   ASSERT_EQ("array[string]", d4.ToString());
159 }
160 
161 }  // namespace arrow
162