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 //! This module provides ScalarValue, an enum that can be used for storage of single elements
19 
20 use std::{convert::TryFrom, fmt, iter::repeat, sync::Arc};
21 
22 use arrow::datatypes::{DataType, Field, IntervalUnit, TimeUnit};
23 use arrow::{
24     array::*,
25     datatypes::{ArrowNativeType, Float32Type, TimestampNanosecondType},
26 };
27 
28 use crate::error::{DataFusionError, Result};
29 
30 /// Represents a dynamically typed, nullable single value.
31 /// This is the single-valued counter-part of arrow’s `Array`.
32 #[derive(Clone, PartialEq)]
33 pub enum ScalarValue {
34     /// true or false value
35     Boolean(Option<bool>),
36     /// 32bit float
37     Float32(Option<f32>),
38     /// 64bit float
39     Float64(Option<f64>),
40     /// signed 8bit int
41     Int8(Option<i8>),
42     /// signed 16bit int
43     Int16(Option<i16>),
44     /// signed 32bit int
45     Int32(Option<i32>),
46     /// signed 64bit int
47     Int64(Option<i64>),
48     /// unsigned 8bit int
49     UInt8(Option<u8>),
50     /// unsigned 16bit int
51     UInt16(Option<u16>),
52     /// unsigned 32bit int
53     UInt32(Option<u32>),
54     /// unsigned 64bit int
55     UInt64(Option<u64>),
56     /// utf-8 encoded string.
57     Utf8(Option<String>),
58     /// utf-8 encoded string representing a LargeString's arrow type.
59     LargeUtf8(Option<String>),
60     /// binary
61     Binary(Option<Vec<u8>>),
62     /// large binary
63     LargeBinary(Option<Vec<u8>>),
64     /// list of nested ScalarValue
65     List(Option<Vec<ScalarValue>>, DataType),
66     /// Date stored as a signed 32bit int
67     Date32(Option<i32>),
68     /// Date stored as a signed 64bit int
69     Date64(Option<i64>),
70     /// Timestamp Microseconds
71     TimeMicrosecond(Option<i64>),
72     /// Timestamp Nanoseconds
73     TimeNanosecond(Option<i64>),
74     /// Interval with YearMonth unit
75     IntervalYearMonth(Option<i32>),
76     /// Interval with DayTime unit
77     IntervalDayTime(Option<i64>),
78 }
79 
80 macro_rules! typed_cast {
81     ($array:expr, $index:expr, $ARRAYTYPE:ident, $SCALAR:ident) => {{
82         let array = $array.as_any().downcast_ref::<$ARRAYTYPE>().unwrap();
83         ScalarValue::$SCALAR(match array.is_null($index) {
84             true => None,
85             false => Some(array.value($index).into()),
86         })
87     }};
88 }
89 
90 macro_rules! build_list {
91     ($VALUE_BUILDER_TY:ident, $SCALAR_TY:ident, $VALUES:expr, $SIZE:expr) => {{
92         match $VALUES {
93             // the return on the macro is necessary, to short-circuit and return ArrayRef
94             None => {
95                 return new_null_array(
96                     &DataType::List(Box::new(Field::new(
97                         "item",
98                         DataType::$SCALAR_TY,
99                         true,
100                     ))),
101                     $SIZE,
102                 )
103             }
104             Some(values) => {
105                 let mut builder = ListBuilder::new($VALUE_BUILDER_TY::new(values.len()));
106 
107                 for _ in 0..$SIZE {
108                     for scalar_value in values {
109                         match scalar_value {
110                             ScalarValue::$SCALAR_TY(Some(v)) => {
111                                 builder.values().append_value(*v).unwrap()
112                             }
113                             ScalarValue::$SCALAR_TY(None) => {
114                                 builder.values().append_null().unwrap();
115                             }
116                             _ => panic!("Incompatible ScalarValue for list"),
117                         };
118                     }
119                     builder.append(true).unwrap();
120                 }
121 
122                 builder.finish()
123             }
124         }
125     }};
126 }
127 
128 impl ScalarValue {
129     /// Getter for the `DataType` of the value
get_datatype(&self) -> DataType130     pub fn get_datatype(&self) -> DataType {
131         match self {
132             ScalarValue::Boolean(_) => DataType::Boolean,
133             ScalarValue::UInt8(_) => DataType::UInt8,
134             ScalarValue::UInt16(_) => DataType::UInt16,
135             ScalarValue::UInt32(_) => DataType::UInt32,
136             ScalarValue::UInt64(_) => DataType::UInt64,
137             ScalarValue::Int8(_) => DataType::Int8,
138             ScalarValue::Int16(_) => DataType::Int16,
139             ScalarValue::Int32(_) => DataType::Int32,
140             ScalarValue::Int64(_) => DataType::Int64,
141             ScalarValue::TimeMicrosecond(_) => {
142                 DataType::Timestamp(TimeUnit::Microsecond, None)
143             }
144             ScalarValue::TimeNanosecond(_) => {
145                 DataType::Timestamp(TimeUnit::Nanosecond, None)
146             }
147             ScalarValue::Float32(_) => DataType::Float32,
148             ScalarValue::Float64(_) => DataType::Float64,
149             ScalarValue::Utf8(_) => DataType::Utf8,
150             ScalarValue::LargeUtf8(_) => DataType::LargeUtf8,
151             ScalarValue::Binary(_) => DataType::Binary,
152             ScalarValue::LargeBinary(_) => DataType::LargeBinary,
153             ScalarValue::List(_, data_type) => {
154                 DataType::List(Box::new(Field::new("item", data_type.clone(), true)))
155             }
156             ScalarValue::Date32(_) => DataType::Date32,
157             ScalarValue::Date64(_) => DataType::Date64,
158             ScalarValue::IntervalYearMonth(_) => {
159                 DataType::Interval(IntervalUnit::YearMonth)
160             }
161             ScalarValue::IntervalDayTime(_) => DataType::Interval(IntervalUnit::DayTime),
162         }
163     }
164 
165     /// Calculate arithmetic negation for a scalar value
arithmetic_negate(&self) -> Self166     pub fn arithmetic_negate(&self) -> Self {
167         match self {
168             ScalarValue::Boolean(None)
169             | ScalarValue::Int8(None)
170             | ScalarValue::Int16(None)
171             | ScalarValue::Int32(None)
172             | ScalarValue::Int64(None)
173             | ScalarValue::Float32(None) => self.clone(),
174             ScalarValue::Float64(Some(v)) => ScalarValue::Float64(Some(-v)),
175             ScalarValue::Float32(Some(v)) => ScalarValue::Float32(Some(-v)),
176             ScalarValue::Int8(Some(v)) => ScalarValue::Int8(Some(-v)),
177             ScalarValue::Int16(Some(v)) => ScalarValue::Int16(Some(-v)),
178             ScalarValue::Int32(Some(v)) => ScalarValue::Int32(Some(-v)),
179             ScalarValue::Int64(Some(v)) => ScalarValue::Int64(Some(-v)),
180             _ => panic!("Cannot run arithmetic negate on scala value: {:?}", self),
181         }
182     }
183 
184     /// whether this value is null or not.
is_null(&self) -> bool185     pub fn is_null(&self) -> bool {
186         matches!(
187             *self,
188             ScalarValue::Boolean(None)
189                 | ScalarValue::UInt8(None)
190                 | ScalarValue::UInt16(None)
191                 | ScalarValue::UInt32(None)
192                 | ScalarValue::UInt64(None)
193                 | ScalarValue::Int8(None)
194                 | ScalarValue::Int16(None)
195                 | ScalarValue::Int32(None)
196                 | ScalarValue::Int64(None)
197                 | ScalarValue::Float32(None)
198                 | ScalarValue::Float64(None)
199                 | ScalarValue::Utf8(None)
200                 | ScalarValue::LargeUtf8(None)
201                 | ScalarValue::List(None, _)
202         )
203     }
204 
205     /// Converts a scalar value into an 1-row array.
to_array(&self) -> ArrayRef206     pub fn to_array(&self) -> ArrayRef {
207         self.to_array_of_size(1)
208     }
209 
210     /// Converts a scalar value into an array of `size` rows.
to_array_of_size(&self, size: usize) -> ArrayRef211     pub fn to_array_of_size(&self, size: usize) -> ArrayRef {
212         match self {
213             ScalarValue::Boolean(e) => {
214                 Arc::new(BooleanArray::from(vec![*e; size])) as ArrayRef
215             }
216             ScalarValue::Float64(e) => match e {
217                 Some(value) => {
218                     Arc::new(Float64Array::from_iter_values(repeat(*value).take(size)))
219                 }
220                 None => new_null_array(&DataType::Float64, size),
221             },
222             ScalarValue::Float32(e) => match e {
223                 Some(value) => {
224                     Arc::new(Float32Array::from_iter_values(repeat(*value).take(size)))
225                 }
226                 None => new_null_array(&DataType::Float32, size),
227             },
228             ScalarValue::Int8(e) => match e {
229                 Some(value) => {
230                     Arc::new(Int8Array::from_iter_values(repeat(*value).take(size)))
231                 }
232                 None => new_null_array(&DataType::Int8, size),
233             },
234             ScalarValue::Int16(e) => match e {
235                 Some(value) => {
236                     Arc::new(Int16Array::from_iter_values(repeat(*value).take(size)))
237                 }
238                 None => new_null_array(&DataType::Int16, size),
239             },
240             ScalarValue::Int32(e) => match e {
241                 Some(value) => {
242                     Arc::new(Int32Array::from_iter_values(repeat(*value).take(size)))
243                 }
244                 None => new_null_array(&DataType::Int32, size),
245             },
246             ScalarValue::Int64(e) => match e {
247                 Some(value) => {
248                     Arc::new(Int64Array::from_iter_values(repeat(*value).take(size)))
249                 }
250                 None => new_null_array(&DataType::Int64, size),
251             },
252             ScalarValue::UInt8(e) => match e {
253                 Some(value) => {
254                     Arc::new(UInt8Array::from_iter_values(repeat(*value).take(size)))
255                 }
256                 None => new_null_array(&DataType::UInt8, size),
257             },
258             ScalarValue::UInt16(e) => match e {
259                 Some(value) => {
260                     Arc::new(UInt16Array::from_iter_values(repeat(*value).take(size)))
261                 }
262                 None => new_null_array(&DataType::UInt16, size),
263             },
264             ScalarValue::UInt32(e) => match e {
265                 Some(value) => {
266                     Arc::new(UInt32Array::from_iter_values(repeat(*value).take(size)))
267                 }
268                 None => new_null_array(&DataType::UInt32, size),
269             },
270             ScalarValue::UInt64(e) => match e {
271                 Some(value) => {
272                     Arc::new(UInt64Array::from_iter_values(repeat(*value).take(size)))
273                 }
274                 None => new_null_array(&DataType::UInt64, size),
275             },
276             ScalarValue::TimeMicrosecond(e) => match e {
277                 Some(value) => Arc::new(TimestampMicrosecondArray::from_iter_values(
278                     repeat(*value).take(size),
279                 )),
280                 None => new_null_array(
281                     &DataType::Timestamp(TimeUnit::Microsecond, None),
282                     size,
283                 ),
284             },
285             ScalarValue::TimeNanosecond(e) => match e {
286                 Some(value) => Arc::new(TimestampNanosecondArray::from_iter_values(
287                     repeat(*value).take(size),
288                 )),
289                 None => {
290                     new_null_array(&DataType::Timestamp(TimeUnit::Nanosecond, None), size)
291                 }
292             },
293             ScalarValue::Utf8(e) => match e {
294                 Some(value) => {
295                     Arc::new(StringArray::from_iter_values(repeat(value).take(size)))
296                 }
297                 None => new_null_array(&DataType::Utf8, size),
298             },
299             ScalarValue::LargeUtf8(e) => match e {
300                 Some(value) => {
301                     Arc::new(LargeStringArray::from_iter_values(repeat(value).take(size)))
302                 }
303                 None => new_null_array(&DataType::LargeUtf8, size),
304             },
305             ScalarValue::Binary(e) => match e {
306                 Some(value) => Arc::new(
307                     repeat(Some(value.as_slice()))
308                         .take(size)
309                         .collect::<BinaryArray>(),
310                 ),
311                 None => {
312                     Arc::new(repeat(None::<&str>).take(size).collect::<BinaryArray>())
313                 }
314             },
315             ScalarValue::LargeBinary(e) => match e {
316                 Some(value) => Arc::new(
317                     repeat(Some(value.as_slice()))
318                         .take(size)
319                         .collect::<LargeBinaryArray>(),
320                 ),
321                 None => Arc::new(
322                     repeat(None::<&str>)
323                         .take(size)
324                         .collect::<LargeBinaryArray>(),
325                 ),
326             },
327             ScalarValue::List(values, data_type) => Arc::new(match data_type {
328                 DataType::Int8 => build_list!(Int8Builder, Int8, values, size),
329                 DataType::Int16 => build_list!(Int16Builder, Int16, values, size),
330                 DataType::Int32 => build_list!(Int32Builder, Int32, values, size),
331                 DataType::Int64 => build_list!(Int64Builder, Int64, values, size),
332                 DataType::UInt8 => build_list!(UInt8Builder, UInt8, values, size),
333                 DataType::UInt16 => build_list!(UInt16Builder, UInt16, values, size),
334                 DataType::UInt32 => build_list!(UInt32Builder, UInt32, values, size),
335                 DataType::UInt64 => build_list!(UInt64Builder, UInt64, values, size),
336                 _ => panic!("Unexpected DataType for list"),
337             }),
338             ScalarValue::Date32(e) => match e {
339                 Some(value) => {
340                     Arc::new(Date32Array::from_iter_values(repeat(*value).take(size)))
341                 }
342                 None => new_null_array(&DataType::Date32, size),
343             },
344             ScalarValue::Date64(e) => match e {
345                 Some(value) => {
346                     Arc::new(Date64Array::from_iter_values(repeat(*value).take(size)))
347                 }
348                 None => new_null_array(&DataType::Date64, size),
349             },
350             ScalarValue::IntervalDayTime(e) => match e {
351                 Some(value) => Arc::new(IntervalDayTimeArray::from_iter_values(
352                     repeat(*value).take(size),
353                 )),
354                 None => new_null_array(&DataType::Interval(IntervalUnit::DayTime), size),
355             },
356             ScalarValue::IntervalYearMonth(e) => match e {
357                 Some(value) => Arc::new(IntervalYearMonthArray::from_iter_values(
358                     repeat(*value).take(size),
359                 )),
360                 None => {
361                     new_null_array(&DataType::Interval(IntervalUnit::YearMonth), size)
362                 }
363             },
364         }
365     }
366 
367     /// Converts a value in `array` at `index` into a ScalarValue
try_from_array(array: &ArrayRef, index: usize) -> Result<Self>368     pub fn try_from_array(array: &ArrayRef, index: usize) -> Result<Self> {
369         Ok(match array.data_type() {
370             DataType::Boolean => typed_cast!(array, index, BooleanArray, Boolean),
371             DataType::Float64 => typed_cast!(array, index, Float64Array, Float64),
372             DataType::Float32 => typed_cast!(array, index, Float32Array, Float32),
373             DataType::UInt64 => typed_cast!(array, index, UInt64Array, UInt64),
374             DataType::UInt32 => typed_cast!(array, index, UInt32Array, UInt32),
375             DataType::UInt16 => typed_cast!(array, index, UInt16Array, UInt16),
376             DataType::UInt8 => typed_cast!(array, index, UInt8Array, UInt8),
377             DataType::Int64 => typed_cast!(array, index, Int64Array, Int64),
378             DataType::Int32 => typed_cast!(array, index, Int32Array, Int32),
379             DataType::Int16 => typed_cast!(array, index, Int16Array, Int16),
380             DataType::Int8 => typed_cast!(array, index, Int8Array, Int8),
381             DataType::Utf8 => typed_cast!(array, index, StringArray, Utf8),
382             DataType::LargeUtf8 => typed_cast!(array, index, LargeStringArray, LargeUtf8),
383             DataType::List(nested_type) => {
384                 let list_array =
385                     array.as_any().downcast_ref::<ListArray>().ok_or_else(|| {
386                         DataFusionError::Internal(
387                             "Failed to downcast ListArray".to_string(),
388                         )
389                     })?;
390                 let value = match list_array.is_null(index) {
391                     true => None,
392                     false => {
393                         let nested_array = list_array.value(index);
394                         let scalar_vec = (0..nested_array.len())
395                             .map(|i| ScalarValue::try_from_array(&nested_array, i))
396                             .collect::<Result<Vec<_>>>()?;
397                         Some(scalar_vec)
398                     }
399                 };
400                 ScalarValue::List(value, nested_type.data_type().clone())
401             }
402             DataType::Date32 => {
403                 typed_cast!(array, index, Date32Array, Date32)
404             }
405             DataType::Date64 => {
406                 typed_cast!(array, index, Date64Array, Date64)
407             }
408             other => {
409                 return Err(DataFusionError::NotImplemented(format!(
410                     "Can't create a scalar of array of type \"{:?}\"",
411                     other
412                 )))
413             }
414         })
415     }
416 }
417 
418 impl From<f64> for ScalarValue {
from(value: f64) -> Self419     fn from(value: f64) -> Self {
420         ScalarValue::Float64(Some(value))
421     }
422 }
423 
424 impl From<f32> for ScalarValue {
from(value: f32) -> Self425     fn from(value: f32) -> Self {
426         ScalarValue::Float32(Some(value))
427     }
428 }
429 
430 impl From<i8> for ScalarValue {
from(value: i8) -> Self431     fn from(value: i8) -> Self {
432         ScalarValue::Int8(Some(value))
433     }
434 }
435 
436 impl From<i16> for ScalarValue {
from(value: i16) -> Self437     fn from(value: i16) -> Self {
438         ScalarValue::Int16(Some(value))
439     }
440 }
441 
442 impl From<i32> for ScalarValue {
from(value: i32) -> Self443     fn from(value: i32) -> Self {
444         ScalarValue::Int32(Some(value))
445     }
446 }
447 
448 impl From<i64> for ScalarValue {
from(value: i64) -> Self449     fn from(value: i64) -> Self {
450         ScalarValue::Int64(Some(value))
451     }
452 }
453 
454 impl From<bool> for ScalarValue {
from(value: bool) -> Self455     fn from(value: bool) -> Self {
456         ScalarValue::Boolean(Some(value))
457     }
458 }
459 
460 impl From<u8> for ScalarValue {
from(value: u8) -> Self461     fn from(value: u8) -> Self {
462         ScalarValue::UInt8(Some(value))
463     }
464 }
465 
466 impl From<u16> for ScalarValue {
from(value: u16) -> Self467     fn from(value: u16) -> Self {
468         ScalarValue::UInt16(Some(value))
469     }
470 }
471 
472 impl From<u32> for ScalarValue {
from(value: u32) -> Self473     fn from(value: u32) -> Self {
474         ScalarValue::UInt32(Some(value))
475     }
476 }
477 
478 impl From<u64> for ScalarValue {
from(value: u64) -> Self479     fn from(value: u64) -> Self {
480         ScalarValue::UInt64(Some(value))
481     }
482 }
483 
484 macro_rules! impl_try_from {
485     ($SCALAR:ident, $NATIVE:ident) => {
486         impl TryFrom<ScalarValue> for $NATIVE {
487             type Error = DataFusionError;
488 
489             fn try_from(value: ScalarValue) -> Result<Self> {
490                 match value {
491                     ScalarValue::$SCALAR(Some(inner_value)) => Ok(inner_value),
492                     _ => Err(DataFusionError::Internal(format!(
493                         "Cannot convert {:?} to {}",
494                         value,
495                         std::any::type_name::<Self>()
496                     ))),
497                 }
498             }
499         }
500     };
501 }
502 
503 impl_try_from!(Int8, i8);
504 impl_try_from!(Int16, i16);
505 
506 // special implementation for i32 because of Date32
507 impl TryFrom<ScalarValue> for i32 {
508     type Error = DataFusionError;
509 
try_from(value: ScalarValue) -> Result<Self>510     fn try_from(value: ScalarValue) -> Result<Self> {
511         match value {
512             ScalarValue::Int32(Some(inner_value))
513             | ScalarValue::Date32(Some(inner_value)) => Ok(inner_value),
514             _ => Err(DataFusionError::Internal(format!(
515                 "Cannot convert {:?} to {}",
516                 value,
517                 std::any::type_name::<Self>()
518             ))),
519         }
520     }
521 }
522 
523 // special implementation for i64 because of TimeNanosecond
524 impl TryFrom<ScalarValue> for i64 {
525     type Error = DataFusionError;
526 
try_from(value: ScalarValue) -> Result<Self>527     fn try_from(value: ScalarValue) -> Result<Self> {
528         match value {
529             ScalarValue::Int64(Some(inner_value))
530             | ScalarValue::TimeNanosecond(Some(inner_value)) => Ok(inner_value),
531             _ => Err(DataFusionError::Internal(format!(
532                 "Cannot convert {:?} to {}",
533                 value,
534                 std::any::type_name::<Self>()
535             ))),
536         }
537     }
538 }
539 
540 impl_try_from!(UInt8, u8);
541 impl_try_from!(UInt16, u16);
542 impl_try_from!(UInt32, u32);
543 impl_try_from!(UInt64, u64);
544 impl_try_from!(Float32, f32);
545 impl_try_from!(Float64, f64);
546 impl_try_from!(Boolean, bool);
547 
548 impl TryFrom<&DataType> for ScalarValue {
549     type Error = DataFusionError;
550 
try_from(datatype: &DataType) -> Result<Self>551     fn try_from(datatype: &DataType) -> Result<Self> {
552         Ok(match datatype {
553             DataType::Boolean => ScalarValue::Boolean(None),
554             DataType::Float64 => ScalarValue::Float64(None),
555             DataType::Float32 => ScalarValue::Float32(None),
556             DataType::Int8 => ScalarValue::Int8(None),
557             DataType::Int16 => ScalarValue::Int16(None),
558             DataType::Int32 => ScalarValue::Int32(None),
559             DataType::Int64 => ScalarValue::Int64(None),
560             DataType::UInt8 => ScalarValue::UInt8(None),
561             DataType::UInt16 => ScalarValue::UInt16(None),
562             DataType::UInt32 => ScalarValue::UInt32(None),
563             DataType::UInt64 => ScalarValue::UInt64(None),
564             DataType::Utf8 => ScalarValue::Utf8(None),
565             DataType::LargeUtf8 => ScalarValue::LargeUtf8(None),
566             DataType::List(ref nested_type) => {
567                 ScalarValue::List(None, nested_type.data_type().clone())
568             }
569             _ => {
570                 return Err(DataFusionError::NotImplemented(format!(
571                     "Can't create a scalar of type \"{:?}\"",
572                     datatype
573                 )))
574             }
575         })
576     }
577 }
578 
579 macro_rules! format_option {
580     ($F:expr, $EXPR:expr) => {{
581         match $EXPR {
582             Some(e) => write!($F, "{}", e),
583             None => write!($F, "NULL"),
584         }
585     }};
586 }
587 
588 impl fmt::Display for ScalarValue {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result589     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
590         match self {
591             ScalarValue::Boolean(e) => format_option!(f, e)?,
592             ScalarValue::Float32(e) => format_option!(f, e)?,
593             ScalarValue::Float64(e) => format_option!(f, e)?,
594             ScalarValue::Int8(e) => format_option!(f, e)?,
595             ScalarValue::Int16(e) => format_option!(f, e)?,
596             ScalarValue::Int32(e) => format_option!(f, e)?,
597             ScalarValue::Int64(e) => format_option!(f, e)?,
598             ScalarValue::UInt8(e) => format_option!(f, e)?,
599             ScalarValue::UInt16(e) => format_option!(f, e)?,
600             ScalarValue::UInt32(e) => format_option!(f, e)?,
601             ScalarValue::UInt64(e) => format_option!(f, e)?,
602             ScalarValue::TimeMicrosecond(e) => format_option!(f, e)?,
603             ScalarValue::TimeNanosecond(e) => format_option!(f, e)?,
604             ScalarValue::Utf8(e) => format_option!(f, e)?,
605             ScalarValue::LargeUtf8(e) => format_option!(f, e)?,
606             ScalarValue::Binary(e) => match e {
607                 Some(l) => write!(
608                     f,
609                     "{}",
610                     l.iter()
611                         .map(|v| format!("{}", v))
612                         .collect::<Vec<_>>()
613                         .join(",")
614                 )?,
615                 None => write!(f, "NULL")?,
616             },
617             ScalarValue::LargeBinary(e) => match e {
618                 Some(l) => write!(
619                     f,
620                     "{}",
621                     l.iter()
622                         .map(|v| format!("{}", v))
623                         .collect::<Vec<_>>()
624                         .join(",")
625                 )?,
626                 None => write!(f, "NULL")?,
627             },
628             ScalarValue::List(e, _) => match e {
629                 Some(l) => write!(
630                     f,
631                     "{}",
632                     l.iter()
633                         .map(|v| format!("{}", v))
634                         .collect::<Vec<_>>()
635                         .join(",")
636                 )?,
637                 None => write!(f, "NULL")?,
638             },
639             ScalarValue::Date32(e) => format_option!(f, e)?,
640             ScalarValue::Date64(e) => format_option!(f, e)?,
641             ScalarValue::IntervalDayTime(e) => format_option!(f, e)?,
642             ScalarValue::IntervalYearMonth(e) => format_option!(f, e)?,
643         };
644         Ok(())
645     }
646 }
647 
648 impl fmt::Debug for ScalarValue {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result649     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
650         match self {
651             ScalarValue::Boolean(_) => write!(f, "Boolean({})", self),
652             ScalarValue::Float32(_) => write!(f, "Float32({})", self),
653             ScalarValue::Float64(_) => write!(f, "Float64({})", self),
654             ScalarValue::Int8(_) => write!(f, "Int8({})", self),
655             ScalarValue::Int16(_) => write!(f, "Int16({})", self),
656             ScalarValue::Int32(_) => write!(f, "Int32({})", self),
657             ScalarValue::Int64(_) => write!(f, "Int64({})", self),
658             ScalarValue::UInt8(_) => write!(f, "UInt8({})", self),
659             ScalarValue::UInt16(_) => write!(f, "UInt16({})", self),
660             ScalarValue::UInt32(_) => write!(f, "UInt32({})", self),
661             ScalarValue::UInt64(_) => write!(f, "UInt64({})", self),
662             ScalarValue::TimeMicrosecond(_) => write!(f, "TimeMicrosecond({})", self),
663             ScalarValue::TimeNanosecond(_) => write!(f, "TimeNanosecond({})", self),
664             ScalarValue::Utf8(None) => write!(f, "Utf8({})", self),
665             ScalarValue::Utf8(Some(_)) => write!(f, "Utf8(\"{}\")", self),
666             ScalarValue::LargeUtf8(None) => write!(f, "LargeUtf8({})", self),
667             ScalarValue::LargeUtf8(Some(_)) => write!(f, "LargeUtf8(\"{}\")", self),
668             ScalarValue::Binary(None) => write!(f, "Binary({})", self),
669             ScalarValue::Binary(Some(_)) => write!(f, "Binary(\"{}\")", self),
670             ScalarValue::LargeBinary(None) => write!(f, "LargeBinary({})", self),
671             ScalarValue::LargeBinary(Some(_)) => write!(f, "LargeBinary(\"{}\")", self),
672             ScalarValue::List(_, _) => write!(f, "List([{}])", self),
673             ScalarValue::Date32(_) => write!(f, "Date32(\"{}\")", self),
674             ScalarValue::Date64(_) => write!(f, "Date64(\"{}\")", self),
675             ScalarValue::IntervalDayTime(_) => {
676                 write!(f, "IntervalDayTime(\"{}\")", self)
677             }
678             ScalarValue::IntervalYearMonth(_) => {
679                 write!(f, "IntervalYearMonth(\"{}\")", self)
680             }
681         }
682     }
683 }
684 
685 /// Trait used to map a NativeTime to a ScalarType.
686 pub trait ScalarType<T: ArrowNativeType> {
687     /// returns a scalar from an optional T
scalar(r: Option<T>) -> ScalarValue688     fn scalar(r: Option<T>) -> ScalarValue;
689 }
690 
691 impl ScalarType<f32> for Float32Type {
scalar(r: Option<f32>) -> ScalarValue692     fn scalar(r: Option<f32>) -> ScalarValue {
693         ScalarValue::Float32(r)
694     }
695 }
696 
697 impl ScalarType<i64> for TimestampNanosecondType {
scalar(r: Option<i64>) -> ScalarValue698     fn scalar(r: Option<i64>) -> ScalarValue {
699         ScalarValue::TimeNanosecond(r)
700     }
701 }
702 
703 #[cfg(test)]
704 mod tests {
705     use super::*;
706 
707     #[test]
scalar_list_null_to_array()708     fn scalar_list_null_to_array() {
709         let list_array_ref = ScalarValue::List(None, DataType::UInt64).to_array();
710         let list_array = list_array_ref.as_any().downcast_ref::<ListArray>().unwrap();
711 
712         assert!(list_array.is_null(0));
713         assert_eq!(list_array.len(), 1);
714         assert_eq!(list_array.values().len(), 0);
715     }
716 
717     #[test]
scalar_list_to_array()718     fn scalar_list_to_array() {
719         let list_array_ref = ScalarValue::List(
720             Some(vec![
721                 ScalarValue::UInt64(Some(100)),
722                 ScalarValue::UInt64(None),
723                 ScalarValue::UInt64(Some(101)),
724             ]),
725             DataType::UInt64,
726         )
727         .to_array();
728 
729         let list_array = list_array_ref.as_any().downcast_ref::<ListArray>().unwrap();
730         assert_eq!(list_array.len(), 1);
731         assert_eq!(list_array.values().len(), 3);
732 
733         let prim_array_ref = list_array.value(0);
734         let prim_array = prim_array_ref
735             .as_any()
736             .downcast_ref::<UInt64Array>()
737             .unwrap();
738         assert_eq!(prim_array.len(), 3);
739         assert_eq!(prim_array.value(0), 100);
740         assert!(prim_array.is_null(1));
741         assert_eq!(prim_array.value(2), 101);
742     }
743 }
744