Skip to content

Commit 972010e

Browse files
committed
refactor(query): refactor variant cast to types
1 parent 53b4ab9 commit 972010e

File tree

3 files changed

+34
-22
lines changed

3 files changed

+34
-22
lines changed

src/query/expression/src/evaluator.rs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -377,14 +377,9 @@ impl<'a> Evaluator<'a> {
377377
.set_span(span))
378378
}
379379
}
380-
(
381-
DataType::Nullable(box DataType::Variant) | DataType::Variant,
382-
DataType::Boolean
383-
| DataType::Number(_)
384-
| DataType::String
385-
| DataType::Date
386-
| DataType::Timestamp,
387-
) => {
380+
(DataType::Nullable(box DataType::Variant) | DataType::Variant, other)
381+
if !other.is_nullable() =>
382+
{
388383
// allow cast variant to not null types.
389384
let cast_fn = format!("to_{}", dest_type.to_string().to_lowercase());
390385
if let Some(new_value) = self.run_simple_cast(
@@ -396,20 +391,13 @@ impl<'a> Evaluator<'a> {
396391
validity.clone(),
397392
options,
398393
)? {
399-
// remove wrapped null values.
400-
let new_value = match new_value {
401-
Value::Scalar(scalar) => {
402-
if scalar == Scalar::Null {
403-
Value::Scalar(Scalar::default_value(dest_type))
404-
} else {
405-
Value::Scalar(scalar)
406-
}
407-
}
408-
Value::Column(column) => {
409-
let nullable_column = column.as_nullable().unwrap();
410-
Value::Column(nullable_column.column.clone())
411-
}
412-
};
394+
let (new_value, has_null) = new_value.remove_nullable();
395+
if has_null {
396+
return Err(ErrorCode::BadArguments(format!(
397+
"unable to cast type `{src_type}` to type `{dest_type}`, result has null values"
398+
))
399+
.set_span(span));
400+
}
413401
Ok(new_value)
414402
} else {
415403
Err(ErrorCode::BadArguments(format!(

src/query/expression/src/values.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,24 @@ impl Value<AnyType> {
345345
}
346346
}
347347

348+
// returns result without nullable and has_null flag
349+
pub fn remove_nullable(self) -> (Self, bool) {
350+
let mut has_null = false;
351+
match self {
352+
Value::Scalar(scalar) => {
353+
if scalar == Scalar::Null {
354+
has_null = true;
355+
}
356+
(Value::Scalar(scalar), has_null)
357+
}
358+
Value::Column(column) => {
359+
let nullable_column = column.as_nullable().unwrap();
360+
has_null = nullable_column.validity.null_count() > 0;
361+
(Value::Column(nullable_column.column.clone()), has_null)
362+
}
363+
}
364+
}
365+
348366
pub fn domain(&self, data_type: &DataType) -> Domain {
349367
match self {
350368
Value::Scalar(scalar) => scalar.as_ref().domain(data_type),

tests/sqllogictests/suites/base/03_common/03_0014_insert_into_select.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,11 @@ SELECT * FROM t5;
142142
{"user_id":1} 1
143143
{"user_id":2} 2
144144

145+
statement ok
146+
INSERT INTO t4 values('{}');
147+
148+
statement error
149+
INSERT INTO t5 SELECT data, data:user_id AS user_id FROM t4;
150+
145151
statement ok
146152
DROP DATABASE db1

0 commit comments

Comments
 (0)