Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cef0300
Preserve common CASE result field metadata without recursive planning
osipovartem Oct 8, 2026
89d9117
Avoid repeated CASE metadata planning through binary expressions
osipovartem Oct 8, 2026
7838313
Resolve scalar UDF CASE metadata iteratively
osipovartem Oct 8, 2026
e225c31
Limit CASE metadata propagation to supported branch forms
osipovartem Oct 8, 2026
217965b
Merge branch 'main' into upstream-case-field-metadata
osipovartem Oct 9, 2026
eac3c68
Cover CASE metadata through bounded function branches
osipovartem Oct 9, 2026
0f8c165
Preserve shallow nested CASE metadata through functions
osipovartem Oct 9, 2026
1ca200b
Test additional CASE metadata branch forms
osipovartem Oct 9, 2026
3a22022
Test CASE metadata across supported leaf expressions
osipovartem Oct 9, 2026
74ac5de
Test CASE field metadata through SQL planning
osipovartem Oct 9, 2026
cc221b5
Test logical CASE field metadata for marked NULL casts
osipovartem Oct 9, 2026
d033855
Test logical CASE metadata depth for marked scalar functions
osipovartem Oct 9, 2026
3a8631b
Test simple CASE field metadata through SQL
osipovartem Oct 9, 2026
c9dbd63
test: cover CASE higher-order and extension metadata
osipovartem Oct 9, 2026
279401f
test: preserve CASE metadata through empty aliases of NULL
osipovartem Oct 9, 2026
90555f7
Merge branch 'main' into upstream-case-field-metadata
osipovartem Oct 9, 2026
3b33f8c
Keep annotated untyped NULL neutral during CASE coercion
osipovartem Oct 9, 2026
1b89bff
Use Arrow-version-independent empty CASE metadata
osipovartem Oct 10, 2026
7cc7ac7
Merge branch 'main' into upstream-case-field-metadata
osipovartem Oct 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions datafusion/core/tests/sql/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use std::collections::HashMap;

use super::*;
use arrow_schema::extension::EXTENSION_TYPE_NAME_KEY;
use datafusion_common::{ParamValues, ScalarValue, metadata::ScalarAndMetadata};
use insta::assert_snapshot;

Expand Down Expand Up @@ -387,6 +388,93 @@ async fn test_query_parameters_with_metadata() -> Result<()> {
Ok(())
}

#[tokio::test]
async fn test_sql_case_field_metadata() -> Result<()> {
let ctx = SessionContext::new();
let metadata = HashMap::from([
("structured_type".to_string(), "ARRAY(NUMBER)".to_string()),
(
EXTENSION_TYPE_NAME_KEY.to_string(),
"example.case".to_string(),
),
]);
let other_metadata = HashMap::from([
("structured_type".to_string(), "OBJECT".to_string()),
(
EXTENSION_TYPE_NAME_KEY.to_string(),
"example.other".to_string(),
),
]);
let schema = Arc::new(Schema::new(vec![
Field::new("flag", DataType::Boolean, false),
Field::new("a", DataType::Int32, false).with_metadata(metadata.clone()),
Field::new("b", DataType::Int32, false).with_metadata(metadata.clone()),
Field::new("c", DataType::Int32, false).with_metadata(other_metadata),
]));
ctx.register_batch(
"t",
RecordBatch::try_new(
schema,
vec![
Arc::new(BooleanArray::from(vec![true, false])),
Arc::new(Int32Array::from(vec![1, 2])),
Arc::new(Int32Array::from(vec![3, 4])),
Arc::new(Int32Array::from(vec![5, 6])),
],
)?,
)?;

let empty_metadata = HashMap::new();
for (sql, preserve_metadata) in [
(
"SELECT CASE WHEN flag THEN a ELSE b END AS value FROM t",
true,
),
(
"SELECT CASE flag WHEN TRUE THEN a ELSE b END AS value FROM t",
true,
),
(
"SELECT CASE WHEN flag THEN a ELSE NULL END AS value FROM t",
true,
),
(
"SELECT CASE WHEN flag THEN NULL ELSE a END AS value FROM t",
true,
),
(
"SELECT CASE WHEN flag THEN a ELSE c END AS value FROM t",
false,
),
] {
let df = ctx.sql(sql).await?;
let optimized = ctx.state().optimize(df.logical_plan())?;
let expected_metadata = if preserve_metadata {
&metadata
} else {
&empty_metadata
};
for field in [df.schema().field(0), optimized.schema().field(0)] {
assert_eq!(field.metadata(), expected_metadata);
}
if sql == "SELECT CASE WHEN flag THEN a ELSE b END AS value FROM t" {
let batches = df.collect().await?;
datafusion::assert_batches_eq!(
[
"+-------+",
"| value |",
"+-------+",
"| 1 |",
"| 4 |",
"+-------+"
],
&batches
);
}
}
Ok(())
}

#[tokio::test]
async fn test_limit_offset_parameters_named() -> Result<()> {
let ctx = SessionContext::new();
Expand Down
Loading
Loading