MCPcopy Create free account
hub / github.com/PRQL/prql / compile_relation_instance

Function compile_relation_instance

prqlc/prqlc/src/sql/pq/gen_query.rs:180–265  ·  view source on GitHub ↗
(riid: RIId, ctx: &mut Context)

Source from the content-addressed store, hash-verified

178}
179
180pub(super) fn compile_relation_instance(riid: RIId, ctx: &mut Context) -> Result<pq::RelationExpr> {
181 ctx.anchor.positional_mapping.activate_mapping(&riid);
182
183 let rel_instance = &ctx.anchor.relation_instances[&riid];
184 let nb_redirects = rel_instance.cid_redirects.len();
185 let table_ref = &rel_instance.table_ref;
186 let source = table_ref.source;
187 let decl = ctx.anchor.table_decls.get_mut(&table_ref.source).unwrap();
188
189 // ensure that the table is declared
190 if let RelationStatus::NotYetDefined(sql_relation) = decl.relation.take_to_define() {
191 // if we cannot use CTEs (probably because we are within RECURSIVE)
192 if !(ctx.query.allow_ctes && table_ref.prefer_cte) {
193 // restore relation for other references
194 decl.relation = RelationStatus::NotYetDefined(sql_relation.clone());
195
196 // return a sub-query
197 let relation = compile_relation(sql_relation, ctx)?;
198 return Ok(pq::RelationExpr {
199 kind: pq::RelationExprKind::SubQuery(relation),
200 riid,
201 });
202 }
203
204 let relation = compile_relation(sql_relation, ctx)?;
205
206 if let pq::SqlRelation::AtomicPipeline(pipeline) = &relation {
207 // Finding the last select statement of the pipeline
208 let last_select_columns = pipeline.iter().rev().find_map(|transform| match transform {
209 pq::SqlTransform::Select(cids) => Some(cids),
210 _ => None,
211 });
212
213 log::debug!("last select CIds for {riid:?}: {last_select_columns:?}");
214
215 // If the pipeline ends with a select, we must recompute its CId redirects
216 if let Some(cids) = last_select_columns {
217 // Only recompute the CId redirects if there are exactly as many columns in the
218 // SELECT as there are CId redirects. This probably means that it is a projecting
219 // select added by `anchor_split`
220 if nb_redirects == cids.len() {
221 log::debug!(
222 "recomputing cid_redirects for {riid:?}. current redirects: {:?}",
223 ctx.anchor.relation_instances[&riid].cid_redirects
224 );
225 // Inefficient but only way to ensure that the new redirects match the original cids
226 let new_redirects = cids
227 .iter()
228 .zip(&ctx.anchor.relation_instances[&riid].original_cids)
229 .map(|(new_cid, original_cid)| {
230 let key_for_value = ctx.anchor.relation_instances[&riid]
231 .cid_redirects
232 .iter()
233 .find_map(|(k, v)| if v == original_cid { Some(k) } else { None })
234 .unwrap();
235
236 (
237 *new_cid,

Callers 1

fold_relMethod · 0.85

Calls 9

compile_relationFunction · 0.85
activate_mappingMethod · 0.80
lenMethod · 0.80
get_mutMethod · 0.80
take_to_defineMethod · 0.80
iterMethod · 0.80
mapMethod · 0.80
pushMethod · 0.80
collectMethod · 0.45

Tested by

no test coverage detected