Skip to content

Commit

Permalink
refine message:
Browse files Browse the repository at this point in the history
- only show "context" in the bottom level
- show struct field name
- do not expose internal impl of map type, instead, show "key" or "value"

Signed-off-by: Bugen Zhao <[email protected]>
  • Loading branch information
BugenZhao committed Nov 21, 2024
1 parent 3a818ae commit fc42233
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 23 deletions.
2 changes: 1 addition & 1 deletion e2e_test/batch/basic/dml_update.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ update t set (v1, v2) = (select '888.88', 999);
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: cannot cast type "record" to "record" in Assign context
1: cannot cast type "record" to "record"
2: cannot cast type "character varying" to "integer" in Assign context


Expand Down
17 changes: 9 additions & 8 deletions src/frontend/planner_test/tests/testdata/output/cast.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
Failed to bind expression: CAST(CAST('[]' AS INT[]) AS BYTEA[])
Caused by these errors (recent errors listed first):
1: cannot cast type "integer[]" to "bytea[]" in Explicit context
1: cannot cast type "integer[]" to "bytea[]"
2: cannot cast type "integer" to "bytea" in Explicit context
- name: composite type cast error message (struct)
sql: |
Expand All @@ -97,9 +97,11 @@
Failed to bind expression: CAST(v AS STRUCT<d STRUCT<e BYTEA>, f BOOLEAN>)
Caused by these errors (recent errors listed first):
1: cannot cast type "struct<a struct<b integer>, c boolean>" to "struct<d struct<e bytea>, f boolean>" in Explicit context
2: cannot cast type "struct<b integer>" to "struct<e bytea>" in Explicit context
3: cannot cast type "integer" to "bytea" in Explicit context
1: cannot cast type "struct<a struct<b integer>, c boolean>" to "struct<d struct<e bytea>, f boolean>"
2: cannot cast struct field "a" to struct field "d"
3: cannot cast type "struct<b integer>" to "struct<e bytea>"
4: cannot cast struct field "b" to struct field "e"
5: cannot cast type "integer" to "bytea" in Explicit context
- name: composite type cast error message (map)
sql: |
create table t (v map(int, int));
Expand All @@ -108,7 +110,6 @@
Failed to bind expression: CAST(v AS MAP(INT,BYTEA))
Caused by these errors (recent errors listed first):
1: cannot cast type "map(integer,integer)" to "map(integer,bytea)" in Explicit context
2: cannot cast type "struct<key integer, value integer>[]" to "struct<key integer, value bytea>[]" in Explicit context
3: cannot cast type "struct<key integer, value integer>" to "struct<key integer, value bytea>" in Explicit context
4: cannot cast type "integer" to "bytea" in Explicit context
1: cannot cast type "map(integer,integer)" to "map(integer,bytea)"
2: cannot cast map value
3: cannot cast type "integer" to "bytea" in Explicit context
58 changes: 44 additions & 14 deletions src/frontend/src/expr/type_inference/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
// limitations under the License.

use std::collections::BTreeMap;
use std::error::Error;
use std::sync::LazyLock;

use itertools::Itertools as _;
use parse_display::Display;
use risingwave_common::types::{DataType, DataTypeName};
use risingwave_common::util::iter_util::ZipEqFast;
use risingwave_common::util::iter_util::{ZipEqDebug, ZipEqFast};

use crate::error::ErrorCode;
use crate::expr::function_call::{bail_cast_error, cast_error, CastError, CastResult};
Expand Down Expand Up @@ -148,12 +149,18 @@ pub fn cast(source: &DataType, target: &DataType, allows: CastContext) -> Result
canmeh(cast_ok_base(source, target, allows))
}
.map_err(|inner| {
// Only show "in .. context" once in the error source chain.
let in_context = if inner.source().is_none() {
&format!(" in {:?} context", allows)
} else {
""
};
cast_error!(
source = inner,
"cannot cast type \"{}\" to \"{}\" in {:?} context",
"cannot cast type \"{}\" to \"{}\"{}",
source,
target,
allows
in_context,
)
})
}
Expand Down Expand Up @@ -181,15 +188,32 @@ fn cast_struct(source: &DataType, target: &DataType, allows: CastContext) -> Cas
bail_cast_error!("cannot cast structs of different lengths");
}
// ... and all fields are castable
lty.types()
.zip_eq_fast(rty.types())
.try_for_each(|(src, dst)| {
if src == dst {
lty.iter().zip_eq_debug(rty.iter()).try_for_each(
|((src_name, src_ty), (dst_name, dst_ty))| {
if src_ty == dst_ty {
Ok(())
} else {
cast(src, dst, allows)
cast(src_ty, dst_ty, allows).map_err(|inner| {
if src_name.is_empty() {
inner
} else if dst_name.is_empty() {
cast_error!(
source = inner,
"cannot cast struct field \"{}\"",
src_name
)
} else {
cast_error!(
source = inner,
"cannot cast struct field \"{}\" to struct field \"{}\"",
src_name,
dst_name
)
}
})
}
})
},
)
}
// The automatic casts to string types are treated as assignment casts, while the automatic
// casts from string types are explicit-only.
Expand All @@ -216,11 +240,17 @@ fn cast_array(source: &DataType, target: &DataType, allows: CastContext) -> Cast

fn cast_map(source: &DataType, target: &DataType, allows: CastContext) -> CastResult {
match (source, target) {
(DataType::Map(source_elem), DataType::Map(target_elem)) => cast(
&source_elem.clone().into_list(),
&target_elem.clone().into_list(),
allows,
),
(DataType::Map(source_elem), DataType::Map(target_elem)) => {
if source_elem.key() != target_elem.key() {
cast(source_elem.key(), target_elem.key(), allows)
.map_err(|inner| cast_error!(source = inner, "cannot cast map key"))?;
}
if source_elem.value() != target_elem.value() {
cast(source_elem.value(), target_elem.value(), allows)
.map_err(|inner| cast_error!(source = inner, "cannot cast map value"))?;
}
Ok(())
}
_ => cannot(),
}
}
Expand Down

0 comments on commit fc42233

Please sign in to comment.