adriangb commented on code in PR #18329:
URL: https://github.com/apache/datafusion/pull/18329#discussion_r2470471026


##########
datafusion/physical-expr/src/expressions/case.rs:
##########
@@ -68,7 +70,106 @@ enum EvalMethod {
     /// if there is just one when/then pair and both the `then` and `else` are 
expressions
     ///
     /// CASE WHEN condition THEN expression ELSE expression END
-    ExpressionOrExpression,
+    ExpressionOrExpression(ProjectedCaseBody),
+}
+
+/// The body of a CASE expression which consists of an optional base 
expression, the "when/then"
+/// branches and an optional "else" branch.
+#[derive(Debug, Hash, PartialEq, Eq)]
+struct CaseBody {
+    /// Optional base expression that can be compared to literal values in the 
"when" expressions
+    expr: Option<Arc<dyn PhysicalExpr>>,
+    /// One or more when/then expressions
+    when_then_expr: Vec<WhenThen>,
+    /// Optional "else" expression
+    else_expr: Option<Arc<dyn PhysicalExpr>>,
+}
+
+impl CaseBody {
+    /// Derives a [ProjectedCaseBody] from this [CaseBody].
+    fn project(&self) -> Result<ProjectedCaseBody> {
+        // Determine the set of columns that are used in all the expressions 
of the case body.
+        let mut used_column_indices = HashSet::<usize>::new();
+        let mut collect_column_indices = |expr: &Arc<dyn PhysicalExpr>| {
+            expr.apply(|expr| {
+                if let Some(column) = expr.as_any().downcast_ref::<Column>() {
+                    used_column_indices.insert(column.index());
+                }
+                Ok(TreeNodeRecursion::Continue)
+            })
+            .expect("Closure cannot fail");
+        };
+
+        if let Some(e) = &self.expr {
+            collect_column_indices(e);
+        }
+        self.when_then_expr.iter().for_each(|(w, t)| {
+            collect_column_indices(w);
+            collect_column_indices(t);
+        });
+        if let Some(e) = &self.else_expr {
+            collect_column_indices(e);
+        }

Review Comment:
   There's `ProjectionExprs::column_indices` which is pub and similar to the 
non-pub `collect_column_indices` referenced above. I haven't reviewed this PR 
in detail but there may be other helper bits that you can use and generally it 
would be nice if we coalesce projection manipulation into `ProjectionExprs` 
because I feel like there's a lot of duplicate code in random places right now 
(obviously needs to be balanced with keeping the API surface area on 
`ProjectionExprs` reasonable).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to