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

Method recursive_cte

datafusion/sql/src/cte.rs:70–184  ·  view source on GitHub ↗
(
        &self,
        cte_name: &str,
        mut cte_query: Query,
        planner_context: &mut PlannerContext,
    )

Source from the content-addressed store, hash-verified

68 }
69
70 fn recursive_cte(
71 &self,
72 cte_name: &str,
73 mut cte_query: Query,
74 planner_context: &mut PlannerContext,
75 ) -> Result<LogicalPlan> {
76 if !self
77 .context_provider
78 .options()
79 .execution
80 .enable_recursive_ctes
81 {
82 return not_impl_err!("Recursive CTEs are not enabled");
83 }
84
85 let (left_expr, right_expr, set_quantifier) = match *cte_query.body {
86 SetExpr::SetOperation {
87 op: SetOperator::Union,
88 left,
89 right,
90 set_quantifier,
91 } => (left, right, set_quantifier),
92 other => {
93 // If the query is not a UNION, then it is not a recursive CTE
94 *cte_query.body = other;
95 return self.non_recursive_cte(cte_query, planner_context);
96 }
97 };
98
99 // Each recursive CTE consists of two parts in the logical plan:
100 // 1. A static term (the left-hand side on the SQL, where the
101 // referencing to the same CTE is not allowed)
102 //
103 // 2. A recursive term (the right hand side, and the recursive
104 // part)
105
106 // Since static term does not have any specific properties, it can
107 // be compiled as if it was a regular expression. This will
108 // allow us to infer the schema to be used in the recursive term.
109
110 // ---------- Step 1: Compile the static term ------------------
111 let static_plan = self.set_expr_to_plan(*left_expr, planner_context)?;
112
113 // Since the recursive CTEs include a component that references a
114 // table with its name, like the example below:
115 //
116 // WITH RECURSIVE values(n) AS (
117 // SELECT 1 as n -- static term
118 // UNION ALL
119 // SELECT n + 1
120 // FROM values -- self reference
121 // WHERE n < 100
122 // )
123 //
124 // We need a temporary 'relation' to be referenced and used. PostgreSQL
125 // calls this a 'working table', but it is entirely an implementation
126 // detail and a 'real' table with that name might not even exist (as
127 // in the case of DataFusion).

Callers 1

plan_with_clauseMethod · 0.80

Calls 14

has_work_table_referenceFunction · 0.85
non_recursive_cteMethod · 0.80
set_expr_to_planMethod · 0.80
insert_cteMethod · 0.80
remove_cteMethod · 0.80
set_operation_to_planMethod · 0.80
to_recursive_queryMethod · 0.80
scanFunction · 0.50
optionsMethod · 0.45
create_cte_work_tableMethod · 0.45
innerMethod · 0.45
schemaMethod · 0.45

Tested by

no test coverage detected