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