From fe5930607427c3c195ce9efd190a93abcc94a545 Mon Sep 17 00:00:00 2001 From: Adam Gutglick Date: Fri, 30 Jan 2026 11:40:24 +0000 Subject: [PATCH 1/2] Fix DF cast pushdown Signed-off-by: Adam Gutglick --- .../src/tests/schema_evolution.rs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/vortex-datafusion/src/tests/schema_evolution.rs b/vortex-datafusion/src/tests/schema_evolution.rs index 658095c64f5..c1b0c7a28b8 100644 --- a/vortex-datafusion/src/tests/schema_evolution.rs +++ b/vortex-datafusion/src/tests/schema_evolution.rs @@ -482,3 +482,35 @@ async fn test_schema_evolution_struct_field_order() -> anyhow::Result<()> { Ok(()) } + +#[tokio::test] +async fn test_cast_int_to_string() -> anyhow::Result<()> { + let ctx = TestSessionContext::default(); + + ctx.session + .sql(r#"copy (select 1 as id) to 'example.vortex'"#) + .await? + .show() + .await?; + + ctx.session + .sql(r#"select cast(id as string) as sid from 'example.vortex' where id > 0"#) + .await? + .show() + .await?; + + ctx.session + .sql(r#"select id from 'example.vortex' where cast (id as string) == '1'"#) + .await? + .show() + .await?; + + // This fails as it pushes string cast to the scan + ctx.session + .sql(r#"select cast(id as string) from 'example.vortex'"#) + .await? + .collect() + .await?; + + Ok(()) +} From 2ce043badd8a6e1c6dbe9e62c88fbfdd626b50cd Mon Sep 17 00:00:00 2001 From: Adam Gutglick Date: Tue, 3 Feb 2026 13:05:27 +0000 Subject: [PATCH 2/2] Add tests that verify issue is there Signed-off-by: Adam Gutglick --- .../src/tests/schema_evolution.rs | 56 ++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/vortex-datafusion/src/tests/schema_evolution.rs b/vortex-datafusion/src/tests/schema_evolution.rs index c1b0c7a28b8..0569f31de45 100644 --- a/vortex-datafusion/src/tests/schema_evolution.rs +++ b/vortex-datafusion/src/tests/schema_evolution.rs @@ -483,6 +483,55 @@ async fn test_schema_evolution_struct_field_order() -> anyhow::Result<()> { Ok(()) } +// https://github.com/vortex-data/vortex/discussions/6264 +#[tokio::test] +#[should_panic(expected = "Failed to convert scalar")] +async fn test_schema_evolution_incompatible_types() { + let ctx = TestSessionContext::default(); + + // File 1: 'code' is UTF8 (string) + ctx.write_arrow_batch( + "files/data_utf8.vortex", + &record_batch!( + ("id", Int64, vec![Some(1i64), Some(2), Some(3)]), + ("code", Utf8, vec![Some("A100"), Some("B200"), Some("C300")]), + ("value", Int64, vec![Some(100i64), Some(200), Some(300)]) + ) + .unwrap(), + ) + .await + .unwrap(); + + // File 2: 'code' is Int64 (SCHEMA CONFLICT!) + ctx.write_arrow_batch( + "files/data_int64.vortex", + &record_batch!( + ("id", Int64, vec![Some(4i64), Some(5), Some(6)]), + ("code", Int64, vec![Some(400i64), Some(500), Some(600)]), + ("value", Int64, vec![Some(400i64), Some(500), Some(600)]) + ) + .unwrap(), + ) + .await + .unwrap(); + + // Query both files with the string schema + ctx.session + .sql( + "CREATE EXTERNAL TABLE my_tbl (id BIGINT, code STRING, value BIGINT) \ + STORED AS vortex \ + LOCATION '/files/'", + ) + .await + .unwrap(); + + let table = ctx.session.table("my_tbl").await.unwrap(); + + // This should panic due to incompatible schema types + table.collect().await.unwrap(); +} + +// https://github.com/vortex-data/vortex/issues/6211 #[tokio::test] async fn test_cast_int_to_string() -> anyhow::Result<()> { let ctx = TestSessionContext::default(); @@ -506,11 +555,14 @@ async fn test_cast_int_to_string() -> anyhow::Result<()> { .await?; // This fails as it pushes string cast to the scan - ctx.session + let result = ctx + .session .sql(r#"select cast(id as string) from 'example.vortex'"#) .await? .collect() - .await?; + .await; + + assert!(result.is_err()); Ok(()) }