Skip to content

Commit b494e97

Browse files
xudong963linhralamb
authored
Deprecate Expr::Wildcard (#14959) (#14976)
* Deprecate `Expr::Wildcard` * Update * Update --------- Co-authored-by: Heran Lin <[email protected]> Co-authored-by: Andrew Lamb <[email protected]>
1 parent 76d833a commit b494e97

File tree

22 files changed

+56
-0
lines changed

22 files changed

+56
-0
lines changed

datafusion/catalog-listing/src/helpers.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ pub fn expr_applicable_for_cols(col_names: &[&str], expr: &Expr) -> bool {
103103
// - AGGREGATE and WINDOW should not end up in filter conditions, except maybe in some edge cases
104104
// - Can `Wildcard` be considered as a `Literal`?
105105
// - ScalarVariable could be `applicable`, but that would require access to the context
106+
// TODO: remove the next line after `Expr::Wildcard` is removed
107+
#[expect(deprecated)]
106108
Expr::AggregateFunction { .. }
107109
| Expr::WindowFunction { .. }
108110
| Expr::Wildcard { .. }

datafusion/expr/src/expr.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ pub enum Expr {
311311
///
312312
/// This expr has to be resolved to a list of columns before translating logical
313313
/// plan into physical plan.
314+
#[deprecated(
315+
since = "46.0.0",
316+
note = "A wildcard needs to be resolved to concrete expressions when constructing the logical plan. See https://github.com/apache/datafusion/issues/7765"
317+
)]
314318
Wildcard {
315319
qualifier: Option<TableReference>,
316320
options: Box<WildcardOptions>,
@@ -1175,6 +1179,7 @@ impl Expr {
11751179
Expr::ScalarVariable(..) => "ScalarVariable",
11761180
Expr::TryCast { .. } => "TryCast",
11771181
Expr::WindowFunction { .. } => "WindowFunction",
1182+
#[expect(deprecated)]
11781183
Expr::Wildcard { .. } => "Wildcard",
11791184
Expr::Unnest { .. } => "Unnest",
11801185
}
@@ -1648,6 +1653,8 @@ impl Expr {
16481653
// Use explicit pattern match instead of a default
16491654
// implementation, so that in the future if someone adds
16501655
// new Expr types, they will check here as well
1656+
// TODO: remove the next line after `Expr::Wildcard` is removed
1657+
#[expect(deprecated)]
16511658
Expr::AggregateFunction(..)
16521659
| Expr::Alias(..)
16531660
| Expr::Between(..)
@@ -2229,6 +2236,7 @@ impl HashNode for Expr {
22292236
Expr::ScalarSubquery(subquery) => {
22302237
subquery.hash(state);
22312238
}
2239+
#[expect(deprecated)]
22322240
Expr::Wildcard { qualifier, options } => {
22332241
qualifier.hash(state);
22342242
options.hash(state);
@@ -2288,6 +2296,8 @@ impl Display for SchemaDisplay<'_> {
22882296
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
22892297
match self.0 {
22902298
// The same as Display
2299+
// TODO: remove the next line after `Expr::Wildcard` is removed
2300+
#[expect(deprecated)]
22912301
Expr::Column(_)
22922302
| Expr::Literal(_)
22932303
| Expr::ScalarVariable(..)
@@ -2758,6 +2768,7 @@ impl Display for Expr {
27582768
write!(f, "{expr} IN ([{}])", expr_vec_fmt!(list))
27592769
}
27602770
}
2771+
#[expect(deprecated)]
27612772
Expr::Wildcard { qualifier, options } => match qualifier {
27622773
Some(qualifier) => write!(f, "{qualifier}.*{options}"),
27632774
None => write!(f, "*{options}"),

datafusion/expr/src/expr_fn.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ pub fn placeholder(id: impl Into<String>) -> Expr {
121121
/// assert_eq!(p.to_string(), "*")
122122
/// ```
123123
pub fn wildcard() -> Expr {
124+
#[expect(deprecated)]
124125
Expr::Wildcard {
125126
qualifier: None,
126127
options: Box::new(WildcardOptions::default()),
@@ -129,6 +130,7 @@ pub fn wildcard() -> Expr {
129130

130131
/// Create an '*' [`Expr::Wildcard`] expression with the wildcard options
131132
pub fn wildcard_with_options(options: WildcardOptions) -> Expr {
133+
#[expect(deprecated)]
132134
Expr::Wildcard {
133135
qualifier: None,
134136
options: Box::new(options),
@@ -146,6 +148,7 @@ pub fn wildcard_with_options(options: WildcardOptions) -> Expr {
146148
/// assert_eq!(p.to_string(), "t.*")
147149
/// ```
148150
pub fn qualified_wildcard(qualifier: impl Into<TableReference>) -> Expr {
151+
#[expect(deprecated)]
149152
Expr::Wildcard {
150153
qualifier: Some(qualifier.into()),
151154
options: Box::new(WildcardOptions::default()),
@@ -157,6 +160,7 @@ pub fn qualified_wildcard_with_options(
157160
qualifier: impl Into<TableReference>,
158161
options: WildcardOptions,
159162
) -> Expr {
163+
#[expect(deprecated)]
160164
Expr::Wildcard {
161165
qualifier: Some(qualifier.into()),
162166
options: Box::new(options),

datafusion/expr/src/expr_rewriter/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ fn coerce_exprs_for_schema(
253253
Expr::Alias(Alias { expr, name, .. }) => {
254254
Ok(expr.cast_to(new_type, src_schema)?.alias(name))
255255
}
256+
#[expect(deprecated)]
256257
Expr::Wildcard { .. } => Ok(expr),
257258
_ => expr.cast_to(new_type, src_schema),
258259
}

datafusion/expr/src/expr_schema.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ impl ExprSchemable for Expr {
215215
Ok(DataType::Null)
216216
}
217217
}
218+
#[expect(deprecated)]
218219
Expr::Wildcard { .. } => Ok(DataType::Null),
219220
Expr::GroupingSet(_) => {
220221
// Grouping sets do not really have a type and do not appear in projections
@@ -329,6 +330,7 @@ impl ExprSchemable for Expr {
329330
| Expr::SimilarTo(Like { expr, pattern, .. }) => {
330331
Ok(expr.nullable(input_schema)? || pattern.nullable(input_schema)?)
331332
}
333+
#[expect(deprecated)]
332334
Expr::Wildcard { .. } => Ok(false),
333335
Expr::GroupingSet(_) => {
334336
// Grouping sets do not really have the concept of nullable and do not appear

datafusion/expr/src/logical_plan/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,7 @@ fn project_with_validation(
16751675
for (e, validate) in expr {
16761676
let e = e.into();
16771677
match e {
1678+
#[expect(deprecated)]
16781679
Expr::Wildcard { .. } => projected_expr.push(e),
16791680
_ => {
16801681
if validate {

datafusion/expr/src/logical_plan/plan.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,6 +2141,7 @@ impl Projection {
21412141
input: Arc<LogicalPlan>,
21422142
schema: DFSchemaRef,
21432143
) -> Result<Self> {
2144+
#[expect(deprecated)]
21442145
if !expr.iter().any(|e| matches!(e, Expr::Wildcard { .. }))
21452146
&& expr.len() != schema.fields().len()
21462147
{
@@ -3451,6 +3452,7 @@ fn calc_func_dependencies_for_project(
34513452
let proj_indices = exprs
34523453
.iter()
34533454
.map(|expr| match expr {
3455+
#[expect(deprecated)]
34543456
Expr::Wildcard { qualifier, options } => {
34553457
let wildcard_fields = exprlist_to_fields(
34563458
vec![&Expr::Wildcard {

datafusion/expr/src/tree_node.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ impl TreeNode for Expr {
6767
Expr::GroupingSet(GroupingSet::GroupingSets(lists_of_exprs)) => {
6868
lists_of_exprs.apply_elements(f)
6969
}
70+
// TODO: remove the next line after `Expr::Wildcard` is removed
71+
#[expect(deprecated)]
7072
Expr::Column(_)
7173
// Treat OuterReferenceColumn as a leaf expression
7274
| Expr::OuterReferenceColumn(_, _)
@@ -113,6 +115,8 @@ impl TreeNode for Expr {
113115
mut f: F,
114116
) -> Result<Transformed<Self>> {
115117
Ok(match self {
118+
// TODO: remove the next line after `Expr::Wildcard` is removed
119+
#[expect(deprecated)]
116120
Expr::Column(_)
117121
| Expr::Wildcard { .. }
118122
| Expr::Placeholder(Placeholder { .. })

datafusion/expr/src/utils.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ pub fn expr_to_columns(expr: &Expr, accum: &mut HashSet<Column>) -> Result<()> {
282282
// Use explicit pattern match instead of a default
283283
// implementation, so that in the future if someone adds
284284
// new Expr types, they will check here as well
285+
// TODO: remove the next line after `Expr::Wildcard` is removed
286+
#[expect(deprecated)]
285287
Expr::Unnest(_)
286288
| Expr::ScalarVariable(_, _)
287289
| Expr::Alias(_)
@@ -709,6 +711,7 @@ pub fn exprlist_to_fields<'a>(
709711
let result = exprs
710712
.into_iter()
711713
.map(|e| match e {
714+
#[expect(deprecated)]
712715
Expr::Wildcard { qualifier, options } => match qualifier {
713716
None => {
714717
let mut excluded = exclude_using_columns(plan)?;
@@ -801,6 +804,7 @@ pub fn exprlist_len(
801804
exprs
802805
.iter()
803806
.map(|e| match e {
807+
#[expect(deprecated)]
804808
Expr::Wildcard {
805809
qualifier: None,
806810
options,
@@ -818,6 +822,7 @@ pub fn exprlist_len(
818822
.len(),
819823
)
820824
}
825+
#[expect(deprecated)]
821826
Expr::Wildcard {
822827
qualifier: Some(qualifier),
823828
options,

datafusion/functions-aggregate/src/planner.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ impl ExprPlanner for AggregateFunctionPlanner {
8282
// handle count() and count(*) case
8383
// convert to count(1) as "count()"
8484
// or count(1) as "count(*)"
85+
// TODO: remove the next line after `Expr::Wildcard` is removed
86+
#[expect(deprecated)]
8587
if raw_expr.func.name() == "count"
8688
&& (raw_expr.args.len() == 1
8789
&& matches!(raw_expr.args[0], Expr::Wildcard { .. })

datafusion/functions-window/src/planner.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ impl ExprPlanner for WindowFunctionPlanner {
7979
null_treatment,
8080
};
8181

82+
// TODO: remove the next line after `Expr::Wildcard` is removed
83+
#[expect(deprecated)]
8284
if raw_expr.func_def.name() == "count"
8385
&& (raw_expr.args.len() == 1
8486
&& matches!(raw_expr.args[0], Expr::Wildcard { .. })

datafusion/optimizer/src/analyzer/expand_wildcard_rule.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ fn expand_exprlist(input: &LogicalPlan, expr: Vec<Expr>) -> Result<Vec<Expr>> {
8989
let input = find_base_plan(input);
9090
for e in expr {
9191
match e {
92+
#[expect(deprecated)]
9293
Expr::Wildcard { qualifier, options } => {
9394
if let Some(qualifier) = qualifier {
9495
let expanded = expand_qualified_wildcard(

datafusion/optimizer/src/analyzer/type_coercion.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,8 @@ impl TreeNodeRewriter for TypeCoercionRewriter<'_> {
565565
.build()?,
566566
))
567567
}
568+
// TODO: remove the next line after `Expr::Wildcard` is removed
569+
#[expect(deprecated)]
568570
Expr::Alias(_)
569571
| Expr::Column(_)
570572
| Expr::ScalarVariable(_, _)
@@ -1021,6 +1023,7 @@ fn project_with_column_index(
10211023
spans: _,
10221024
}) if name != schema.field(i).name() => Ok(e.alias(schema.field(i).name())),
10231025
Expr::Alias { .. } | Expr::Column { .. } => Ok(e),
1026+
#[expect(deprecated)]
10241027
Expr::Wildcard { .. } => {
10251028
plan_err!("Wildcard should be expanded before type coercion")
10261029
}

datafusion/optimizer/src/common_subexpr_eliminate.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,8 @@ impl CSEController for ExprCSEController<'_> {
678678
}
679679

680680
fn is_ignored(&self, node: &Expr) -> bool {
681+
// TODO: remove the next line after `Expr::Wildcard` is removed
682+
#[expect(deprecated)]
681683
let is_normal_minus_aggregates = matches!(
682684
node,
683685
Expr::Literal(..)

datafusion/optimizer/src/push_down_filter.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ fn can_evaluate_as_join_condition(predicate: &Expr) -> Result<bool> {
285285
| Expr::TryCast(_)
286286
| Expr::InList { .. }
287287
| Expr::ScalarFunction(_) => Ok(TreeNodeRecursion::Continue),
288+
// TODO: remove the next line after `Expr::Wildcard` is removed
289+
#[expect(deprecated)]
288290
Expr::AggregateFunction(_)
289291
| Expr::WindowFunction(_)
290292
| Expr::Wildcard { .. }

datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,8 @@ impl<'a> ConstEvaluator<'a> {
582582
// added they can be checked for their ability to be evaluated
583583
// at plan time
584584
match expr {
585+
// TODO: remove the next line after `Expr::Wildcard` is removed
586+
#[expect(deprecated)]
585587
Expr::AggregateFunction { .. }
586588
| Expr::ScalarVariable(_, _)
587589
| Expr::Column(_)

datafusion/proto/src/logical_plan/from_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ pub fn parse_expr(
527527
))),
528528
ExprType::Wildcard(protobuf::Wildcard { qualifier }) => {
529529
let qualifier = qualifier.to_owned().map(|x| x.try_into()).transpose()?;
530+
#[expect(deprecated)]
530531
Ok(Expr::Wildcard {
531532
qualifier,
532533
options: Box::new(WildcardOptions::default()),

datafusion/proto/src/logical_plan/to_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ pub fn serialize_expr(
560560
expr_type: Some(ExprType::InList(expr)),
561561
}
562562
}
563+
#[expect(deprecated)]
563564
Expr::Wildcard { qualifier, .. } => protobuf::LogicalExprNode {
564565
expr_type: Some(ExprType::Wildcard(protobuf::Wildcard {
565566
qualifier: qualifier.to_owned().map(|x| x.into()),

datafusion/sql/src/expr/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,10 +593,12 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
593593
}
594594
not_impl_err!("AnyOp not supported by ExprPlanner: {binary_expr:?}")
595595
}
596+
#[expect(deprecated)]
596597
SQLExpr::Wildcard(_token) => Ok(Expr::Wildcard {
597598
qualifier: None,
598599
options: Box::new(WildcardOptions::default()),
599600
}),
601+
#[expect(deprecated)]
600602
SQLExpr::QualifiedWildcard(object_name, _token) => Ok(Expr::Wildcard {
601603
qualifier: Some(self.object_name_to_table_reference(object_name)?),
602604
options: Box::new(WildcardOptions::default()),

datafusion/sql/src/unparser/expr.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ impl Unparser<'_> {
429429
})
430430
}
431431
// TODO: unparsing wildcard addition options
432+
#[expect(deprecated)]
432433
Expr::Wildcard { qualifier, .. } => {
433434
let attached_token = AttachedToken::empty();
434435
if let Some(qualifier) = qualifier {
@@ -729,6 +730,7 @@ impl Unparser<'_> {
729730
) -> Result<Vec<ast::FunctionArg>> {
730731
args.iter()
731732
.map(|e| {
733+
#[expect(deprecated)]
732734
if matches!(
733735
e,
734736
Expr::Wildcard {
@@ -1715,6 +1717,7 @@ mod tests {
17151717
#[test]
17161718
fn expr_to_sql_ok() -> Result<()> {
17171719
let dummy_schema = Schema::new(vec![Field::new("a", DataType::Int32, false)]);
1720+
#[expect(deprecated)]
17181721
let dummy_logical_plan = table_scan(Some("t"), &dummy_schema, None)?
17191722
.project(vec![Expr::Wildcard {
17201723
qualifier: None,

datafusion/sql/src/utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ pub(crate) fn rewrite_recursive_unnest_bottom_up(
632632
} = original_expr.clone().rewrite(&mut rewriter)?;
633633

634634
if !transformed {
635+
// TODO: remove the next line after `Expr::Wildcard` is removed
636+
#[expect(deprecated)]
635637
if matches!(&transformed_expr, Expr::Column(_))
636638
|| matches!(&transformed_expr, Expr::Wildcard { .. })
637639
{

datafusion/substrait/src/logical_plan/producer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,7 @@ pub fn to_substrait_rex(
13661366
Expr::ScalarSubquery(expr) => {
13671367
not_impl_err!("Cannot convert {expr:?} to Substrait")
13681368
}
1369+
#[expect(deprecated)]
13691370
Expr::Wildcard { .. } => not_impl_err!("Cannot convert {expr:?} to Substrait"),
13701371
Expr::GroupingSet(expr) => not_impl_err!("Cannot convert {expr:?} to Substrait"),
13711372
Expr::Placeholder(expr) => not_impl_err!("Cannot convert {expr:?} to Substrait"),

0 commit comments

Comments
 (0)