MCPcopy Create free account
hub / github.com/apache/datafusion / check_subquery_expr

Function check_subquery_expr

datafusion/expr/src/logical_plan/invariants.rs:157–266  ·  view source on GitHub ↗

Do necessary check on subquery expressions and fail the invalid plan 1) Check whether the outer plan is in the allowed outer plans list to use subquery expressions, the allowed while list: [Projection, Filter, Window, Aggregate, Join]. 2) Check whether the inner plan is in the allowed inner plans list to use correlated(outer) expressions. 3) Check and validate unsupported cases to use the correlat

(
    outer_plan: &LogicalPlan,
    inner_plan: &LogicalPlan,
    expr: &Expr,
)

Source from the content-addressed store, hash-verified

155/// For example, we do not want to support to use correlated expressions as the Join conditions in the subquery plan when the Join
156/// is a Full Out Join
157pub fn check_subquery_expr(
158 outer_plan: &LogicalPlan,
159 inner_plan: &LogicalPlan,
160 expr: &Expr,
161) -> Result<()> {
162 assert_subqueries_are_valid(inner_plan)?;
163 if let Expr::ScalarSubquery(subquery) = expr {
164 // Scalar subquery should only return one column
165 if subquery.subquery.schema().fields().len() > 1 {
166 return plan_err!(
167 "Scalar subquery should only return one column, but found {}: {}",
168 subquery.subquery.schema().fields().len(),
169 subquery.subquery.schema().field_names().join(", ")
170 );
171 }
172 // Correlated scalar subquery must be aggregated to return at most one row
173 if !subquery.outer_ref_columns.is_empty() {
174 match strip_inner_query(inner_plan) {
175 LogicalPlan::Aggregate(agg) => {
176 check_aggregation_in_scalar_subquery(inner_plan, agg)
177 }
178 LogicalPlan::Filter(Filter { input, .. })
179 if matches!(input.as_ref(), LogicalPlan::Aggregate(_)) =>
180 {
181 if let LogicalPlan::Aggregate(agg) = input.as_ref() {
182 check_aggregation_in_scalar_subquery(inner_plan, agg)
183 } else {
184 Ok(())
185 }
186 }
187 _ => {
188 if inner_plan
189 .max_rows()
190 .filter(|max_row| *max_row <= 1)
191 .is_some()
192 {
193 Ok(())
194 } else {
195 plan_err!(
196 "Correlated scalar subquery must be aggregated to return at most one row"
197 )
198 }
199 }
200 }?;
201 match outer_plan {
202 LogicalPlan::Projection(_) | LogicalPlan::Filter(_) => Ok(()),
203 LogicalPlan::Aggregate(Aggregate {
204 group_expr,
205 aggr_expr,
206 ..
207 }) => {
208 if group_expr.contains(expr) && !aggr_expr.contains(expr) {
209 // TODO revisit this validation logic
210 plan_err!(
211 "Correlated scalar subquery in the GROUP BY clause must \
212 also be in the aggregate expressions"
213 )
214 } else {

Callers 1

Calls 12

strip_inner_queryFunction · 0.85
max_rowsMethod · 0.80
lenMethod · 0.45
fieldsMethod · 0.45
schemaMethod · 0.45
is_emptyMethod · 0.45
as_refMethod · 0.45
filterMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…