1pub mod build_result;
3pub mod select_stream;
4pub mod sql_builder_error;
5
6pub(crate) mod build_context;
7pub(crate) mod path_tree;
8
9use crate::{
10 error::ToqlError,
11 parameter_map::ParameterMap,
12 query::{
13 concatenation::Concatenation, field_order::FieldOrder, field_path::FieldPath,
14 query_token::QueryToken, Query,
15 },
16 result::Result,
17 role_validator::RoleValidator,
18 sql_arg::SqlArg,
19 sql_builder::{
20 build_context::BuildContext, build_result::BuildResult, sql_builder_error::SqlBuilderError,
21 },
22 sql_expr::{resolver::Resolver, SqlExpr},
23 table_mapper::{join_type::JoinType, DeserializeType, TableMapper},
24 table_mapper_registry::TableMapperRegistry,
25};
26
27use path_tree::PathTree;
28use select_stream::Select;
29use std::{
30 borrow::Cow,
31 collections::{HashMap, HashSet},
32};
33
34enum MapperOrMerge<'a> {
35 Mapper(&'a TableMapper),
36 Merge(String),
37}
38
39pub struct SqlBuilder<'a> {
41 root_mapper: String, home_mapper: String, table_mapper_registry: &'a TableMapperRegistry,
44 roles: HashSet<String>,
45 aux_params: HashMap<String, SqlArg>, extra_joins: HashSet<String>, }
48
49impl<'a> SqlBuilder<'a> {
50 pub fn new(root_mapper: &'a str, table_mapper_registry: &'a TableMapperRegistry) -> Self {
52 SqlBuilder {
53 root_mapper: root_mapper.to_string(),
54 home_mapper: root_mapper.to_string(),
55 table_mapper_registry,
56 roles: HashSet::new(),
57 aux_params: HashMap::new(),
58 extra_joins: HashSet::new(),
59 }
60 }
61 pub fn with_roles(mut self, roles: HashSet<String>) -> Self {
63 self.roles = roles;
64 self
65 }
66 pub fn with_aux_params(mut self, aux_params: HashMap<String, SqlArg>) -> Self {
68 self.aux_params = aux_params;
69 self
70 }
71 pub fn with_extra_join<T: Into<String>>(mut self, join: T) -> Self {
74 self.extra_joins.insert(join.into());
75 self
76 }
77
78 pub fn columns_expr(&self, query_field_path: &str, alias: &str) -> Result<(SqlExpr, SqlExpr)> {
79 let mut columns_expr = SqlExpr::new();
80 let mut join_expr = SqlExpr::new();
81
82 self.resolve_columns_expr(
83 query_field_path,
84 alias,
85 &mut columns_expr,
86 &mut join_expr,
87 )?;
89
90 Ok((columns_expr, join_expr))
91 }
92 fn resolve_columns_expr(
93 &self,
94 query_path: &str,
95 alias: &str,
96 columns_expr: &mut SqlExpr,
97 join_expr: &mut SqlExpr,
98 ) -> Result<()> {
100 let mapper = self.mapper_for_query_path(&FieldPath::from(query_path))?;
101
102 for order in &mapper.deserialize_order {
103 match order {
104 DeserializeType::Field(name) => {
105 let field = mapper
106 .field(&name)
107 .ok_or_else(|| SqlBuilderError::FieldMissing(name.to_string()))?;
108 if !field.options.key {
109 return Ok(());
110 }
111 let resolver = Resolver::new().with_self_alias(alias);
112 if !columns_expr.is_empty() {
113 columns_expr.push_literal(", ");
114 }
115 columns_expr.extend(resolver.resolve(&field.expression)?);
116 }
117 DeserializeType::Join(name) => {
118 let join = mapper.join(&name).ok_or_else(|| {
119 SqlBuilderError::JoinMissing(
120 name.to_string(),
121 mapper.table_name.to_string(),
122 )
123 })?;
124 if !join.options.key {
125 return Ok(());
126 }
127 let other_alias = FieldPath::from(alias).append(&mapper.canonical_table_alias);
128 let resolver = Resolver::new()
129 .with_self_alias(alias)
130 .with_other_alias(&other_alias);
131
132 join_expr.push_literal("JOIN ");
133 join_expr.extend(resolver.resolve(&join.table_expression)?);
134 join_expr.push_literal(" ON (");
135 join_expr.extend(resolver.resolve(&join.on_expression)?);
136 join_expr.push_literal(") ");
137
138 let joined_query_path = FieldPath::from(query_path).append(&name);
139
140 self.resolve_columns_expr(
141 &joined_query_path,
142 &other_alias,
143 columns_expr,
144 join_expr,
145 )?;
147 }
148
149 DeserializeType::Merge(_) => {}
150 }
151 }
152 Ok(())
153 }
154
155 pub fn merge_expr(&self, query_field_path: &str) -> Result<(SqlExpr, SqlExpr)> {
156 let (query_path, basename) = FieldPath::split_basename(query_field_path);
157 let mapper = self.mapper_for_query_path(&query_path)?;
158
159 let merge = mapper.merge(basename).ok_or(ToqlError::NotFound)?;
161
162 Ok((
163 merge.merge_join.to_owned(),
164 merge.merge_predicate.to_owned(),
165 ))
166 }
167
168 pub fn build_delete<M>(&mut self, query: &Query<M>) -> Result<BuildResult> {
174 let mut context = BuildContext::new();
175 let root_mapper = self
176 .table_mapper_registry
177 .mappers
178 .get(&self.home_mapper)
179 .ok_or_else(|| ToqlError::MapperMissing(self.home_mapper.to_owned()))?;
180
181 if let Some(role_expr) = &root_mapper.delete_role_expr {
182 if !RoleValidator::is_valid(&self.roles, role_expr) {
183 return Err(SqlBuilderError::RoleRequired(
184 role_expr.to_string(),
185 format!("mapper `{}`", self.home_mapper.to_string(),),
186 )
187 .into());
188 }
189 }
190
191 let mut result = BuildResult::new(SqlExpr::literal("DELETE"));
192
193 result.set_from(
194 root_mapper.table_name.to_owned(),
195 root_mapper.canonical_table_alias.to_owned(),
196 );
197 self.preparse_filter_joins(&query, &mut context, false)?;
198 self.build_where_clause(&query, &mut context, false, &mut result)?;
199 self.build_join_clause(&query.aux_params, &mut context, &mut result, true, false)?;
200
201 Ok(result)
202 }
203
204 pub fn build_merge_delete(
206 &mut self,
207 merge_path: &FieldPath,
208 key_predicate: SqlExpr,
209 ) -> Result<SqlExpr> {
210 let root_mapper = self
211 .table_mapper_registry
212 .mappers
213 .get(&self.home_mapper)
214 .ok_or_else(|| ToqlError::MapperMissing(self.home_mapper.to_owned()))?;
215
216 let (query_path, merge_field) = FieldPath::split_basename(&merge_path);
217
218 let base_mapper = self.mapper_for_query_path(&query_path)?;
219 let root_path = FieldPath::from(&root_mapper.canonical_table_alias);
220 let canonical_path = root_path.append(&query_path);
221
222 let merge = base_mapper
223 .merge(merge_field)
224 .ok_or_else(|| SqlBuilderError::FieldMissing(merge_field.to_string()))?;
225
226 let merge_mapper = self
227 .table_mapper_registry
228 .mappers
229 .get(&merge.merged_mapper)
230 .ok_or_else(|| ToqlError::MapperMissing(merge.merged_mapper.to_string()))?;
231
232 let mut delete_expr = SqlExpr::new();
233
234 delete_expr.push_literal("DELETE ");
237 delete_expr.push_other_alias();
238 delete_expr.push_literal(" FROM ");
239 delete_expr.push_literal(&merge_mapper.table_name);
240 delete_expr.push_literal(" ");
241 delete_expr.push_other_alias();
242 delete_expr.push_literal(" ");
243 delete_expr.extend(merge.merge_join.clone()); delete_expr.push_literal(" ON ");
245 delete_expr.extend(merge.merge_predicate.clone());
246 delete_expr.push_literal(" WHERE ");
247 delete_expr.extend(key_predicate);
248
249 let canonical_merge_alias = canonical_path.append(merge_field);
250 let resolver = Resolver::new()
251 .with_self_alias(&canonical_path)
252 .with_other_alias(&canonical_merge_alias);
253
254 resolver.resolve(&delete_expr).map_err(ToqlError::from)
255 }
256
257 pub fn build_select<M>(
261 &mut self,
262 query_home_path: &str,
263 query: &Query<M>,
264 ) -> Result<BuildResult> {
265 let mut context = BuildContext::new();
266 context.query_home_path = query_home_path.to_string();
267
268 self.set_home_joined_mapper_for_path(&FieldPath::from(query_home_path))?;
269
270 let mapper = self
271 .table_mapper_registry
272 .get(&self.home_mapper)
273 .ok_or_else(|| ToqlError::MapperMissing(self.home_mapper.to_string()))?;
274
275 if let Some(role) = mapper.load_role_expr.as_ref() {
276 if !RoleValidator::is_valid(&self.roles, role) {
277 return Err(SqlBuilderError::RoleRequired(
278 role.to_string(),
279 if query_home_path.is_empty() {
280 format!("mapper `{}`", &self.home_mapper)
281 } else {
282 format!("path `{}`", query_home_path)
283 },
284 )
285 .into());
286 }
287 }
288
289 let mut result = BuildResult::new(SqlExpr::literal("SELECT"));
290 result.set_from(
291 mapper.table_name.to_owned(),
292 mapper.canonical_table_alias.to_owned(),
293 );
294
295 self.preparse_query(&query, &mut context, &mut result)?;
296 self.build_where_clause(&query, &mut context, false, &mut result)?;
297 self.build_select_clause(&query, &mut context, &mut result)?;
298 self.build_join_clause(&query.aux_params, &mut context, &mut result, false, true)?;
299 self.build_order_clause(&query.aux_params, &mut context, &mut result)?;
300
301 Ok(result)
302 }
303
304 pub fn build_count<M>(
311 &mut self,
312 query_root_path: &str,
313 query: &Query<M>,
314 count_selection_only: bool,
315 ) -> Result<BuildResult> {
316 let mut build_context = BuildContext::new();
317 build_context.query_home_path = query_root_path.to_string();
318 let root_mapper = self.root_mapper()?; let mut result = BuildResult::new(SqlExpr::literal("SELECT"));
321 result.select_expr.push_literal("COUNT(*)");
322
323 result.set_from(
324 root_mapper.table_name.to_owned(),
325 root_mapper.canonical_table_alias.to_owned(),
326 );
327
328 self.build_where_clause(
329 &query,
330 &mut build_context,
331 count_selection_only,
332 &mut result,
333 )?;
334
335 self.preparse_filter_joins(&query, &mut build_context, count_selection_only)?;
336
337 self.build_join_clause(
338 &query.aux_params,
339 &mut build_context,
340 &mut result,
341 true,
342 true,
343 )?;
344
345 Ok(result)
346 }
347
348 pub fn joined_mapper_for_local_path(&self, local_path: &FieldPath) -> Result<&TableMapper> {
349 self.joined_mapper_for_path(&self.home_mapper, local_path)
350 }
351 pub fn joined_mapper_for_query_path(&self, query_path: &FieldPath) -> Result<&TableMapper> {
352 self.joined_mapper_for_path(&self.root_mapper, query_path)
353 }
354 fn joined_mapper_for_path(&self, mapper_name: &str, path: &FieldPath) -> Result<&TableMapper> {
355 let mut current_mapper = self
356 .table_mapper_registry
357 .get(mapper_name)
358 .ok_or_else(|| ToqlError::MapperMissing(mapper_name.to_string()))?;
359
360 if !path.is_empty() {
361 for p in path.children() {
362 if let Some(join) = current_mapper.joins.get(p.as_str()) {
363 current_mapper = self
364 .table_mapper_registry
365 .get(&join.joined_mapper)
366 .ok_or_else(|| ToqlError::MapperMissing(join.joined_mapper.to_string()))?;
367 } else {
368 return Err(SqlBuilderError::JoinMissing(
369 p.to_string(),
370 current_mapper.table_name.to_string(),
371 )
372 .into());
373 }
374 }
375 }
376
377 Ok(current_mapper)
378 }
379
380 pub fn mapper_for_query_path(&self, query_path: &FieldPath) -> Result<&TableMapper> {
381 let mut current_mapper = self
382 .table_mapper_registry
383 .get(&self.root_mapper)
384 .ok_or_else(|| ToqlError::MapperMissing(self.root_mapper.to_string()))?;
385
386 if !query_path.is_empty() {
387 for p in query_path.children() {
388 if let Some(join) = current_mapper.joins.get(p.as_str()) {
389 current_mapper = self
390 .table_mapper_registry
391 .get(&join.joined_mapper)
392 .ok_or_else(|| ToqlError::MapperMissing(join.joined_mapper.to_string()))?;
393 } else if let Some(merge) = current_mapper.merges.get(p.as_str()) {
394 current_mapper = self
395 .table_mapper_registry
396 .get(&merge.merged_mapper)
397 .ok_or_else(|| ToqlError::MapperMissing(merge.merged_mapper.to_string()))?;
398 } else {
399 return Err(ToqlError::MapperMissing(p.to_string()));
400 }
401 }
402 }
403
404 Ok(current_mapper)
405 }
406
407 fn mapper_or_merge_for_path(&'a self, local_path: &'a FieldPath) -> Result<MapperOrMerge<'a>> {
408 let mut current_mapper = self
409 .table_mapper_registry
410 .get(&self.home_mapper)
411 .ok_or_else(|| ToqlError::MapperMissing(self.home_mapper.to_string()))?;
412
413 if !local_path.is_empty() {
414 for (p, a) in local_path.children().zip(local_path.step_down()) {
415 if current_mapper.merges.contains_key(p.as_str()) {
417 return Ok(MapperOrMerge::Merge(a.to_string()));
418 }
419 let join = current_mapper
420 .joins
421 .get(p.as_str())
422 .ok_or_else(|| ToqlError::MapperMissing(p.to_string()))?;
423 current_mapper = self
424 .table_mapper_registry
425 .get(&join.joined_mapper)
426 .ok_or_else(|| ToqlError::MapperMissing(self.home_mapper.to_string()))?;
427 }
428 }
429
430 Ok(MapperOrMerge::Mapper(current_mapper))
431 }
432 fn set_home_joined_mapper_for_path(&mut self, path: &FieldPath) -> Result<()> {
433 if !path.is_empty() {
434 let mut current_type: &str = &self.root_mapper;
435 let mut current_mapper = self
436 .table_mapper_registry
437 .get(current_type)
438 .ok_or_else(|| ToqlError::MapperMissing(current_type.to_string()))?;
439
440 for p in path.children() {
441 if let Some(merge) = current_mapper.merges.get(p.as_str()) {
442 current_mapper = self
443 .table_mapper_registry
444 .get(&merge.merged_mapper)
445 .ok_or_else(|| ToqlError::MapperMissing(merge.merged_mapper.to_string()))?;
446 current_type = &merge.merged_mapper;
447 } else if let Some(join) = current_mapper.joins.get(p.as_str()) {
448 current_mapper = self
449 .table_mapper_registry
450 .get(&join.joined_mapper)
451 .ok_or_else(|| ToqlError::MapperMissing(join.joined_mapper.to_string()))?;
452 current_type = &join.joined_mapper;
453 } else {
454 return Err(ToqlError::MapperMissing(p.to_string()));
455 }
456 }
457
458 self.home_mapper = current_type.to_string();
459 }
460
461 Ok(())
462 }
463
464 fn build_join_clause(
465 &self,
466 query_aux_params: &HashMap<String, SqlArg>,
467 mut build_context: &mut BuildContext,
468 result: &mut BuildResult,
469 enforce_inner_joins: bool,
470 restrict_load: bool,
471 ) -> Result<()> {
472 let mut join_tree = PathTree::new();
480
481 for local_path in &build_context.local_joined_paths {
482 join_tree.insert(&FieldPath::from(&local_path));
483 }
484
485 let expr: SqlExpr = self.resolve_join(
487 &join_tree,
488 &join_tree.roots(),
489 &mut build_context,
490 enforce_inner_joins,
491 restrict_load,
492 query_aux_params,
493 )?;
494 result.join_expr.extend(expr);
495 result.join_expr.pop_literals(1); Ok(())
498 }
499 fn resolve_join(
500 &self,
501 join_tree: &PathTree,
502 nodes: &HashSet<String>,
503 build_context: &mut BuildContext,
504 enforce_inner_joins: bool,
505 restrict_load: bool,
506 query_aux_params: &HashMap<String, SqlArg>,
507 ) -> Result<SqlExpr> {
508 let mut join_expr = SqlExpr::new();
509
510 for local_path_with_join in nodes {
511 let (local_path, join_name) = FieldPath::split_basename(local_path_with_join);
512
513 let local_mapper = self.joined_mapper_for_local_path(&local_path)?;
514
515 let join = local_mapper.join(join_name).ok_or_else(|| {
516 SqlBuilderError::JoinMissing(
517 join_name.to_string(),
518 local_mapper.table_name.to_string(),
519 )
520 })?;
521 if restrict_load {
522 let joined_mapper = self
523 .table_mapper_registry
524 .get(&join.joined_mapper)
525 .ok_or_else(|| ToqlError::MapperMissing(join.joined_mapper.to_string()))?;
526
527 if let Some(role) = joined_mapper.load_role_expr.as_ref() {
528 if !RoleValidator::is_valid(&self.roles, role) {
529 return Err(SqlBuilderError::RoleRequired(
530 role.to_string(),
531 format!(
532 "path `{}`",
533 FieldPath::from(&build_context.query_home_path)
534 .append(&local_path)
535 .to_string(),
536 ),
537 )
538 .into());
539 }
540 }
541 }
542
543 let canonical_self_alias = self.canonical_alias(&local_path)?.to_string();
544 let canonical_other_alias = self
545 .canonical_alias(&FieldPath::from(local_path_with_join))?
546 .to_string();
547 let resolver = Resolver::new()
548 .with_self_alias(&canonical_self_alias)
549 .with_other_alias(&canonical_other_alias);
550
551 join_expr.push_literal(if enforce_inner_joins {
552 "JOIN ("
553 } else {
554 match &join.join_type {
555 JoinType::Inner => "JOIN (",
556 JoinType::Left => "LEFT JOIN (",
557 }
558 });
559 let join_e = resolver.resolve(&join.table_expression)?;
560 join_expr.extend(join_e);
561 join_expr.push_literal(" ");
562
563 if let Some(subnodes) = join_tree.nodes(local_path_with_join) {
564 if !subnodes.is_empty() {
565 let subjoin_expr = self.resolve_join(
566 join_tree,
567 &subnodes,
568 build_context,
569 enforce_inner_joins,
570 restrict_load,
571 query_aux_params,
572 )?;
573 if !subjoin_expr.is_empty() {
574 join_expr.extend(subjoin_expr);
575 }
576 }
577 }
578 join_expr.pop_literals(1); join_expr.push_literal(") ON (".to_string());
580
581 let on_expr = resolver.resolve(&join.on_expression)?;
582
583 let on_expr = {
584 let p = [
585 &self.aux_params,
586 &join.options.aux_params,
587 &build_context.on_aux_params,
588 &query_aux_params,
589 ];
590 let aux_params = ParameterMap::new(&p);
591 match &join.options.join_handler {
592 Some(handler) => handler.build_on_predicate(on_expr, &aux_params)?,
593 None => Resolver::resolve_aux_params(on_expr, &aux_params),
594 }
595 };
596
597 let on_expr = match on_expr.first_aux_param() {
599 Some(p) if join.join_type == JoinType::Left => {
600 let query_path_with_join = FieldPath::from(&build_context.query_home_path)
601 .append(local_path_with_join);
602 tracing::info!("Setting condition of left join `{}` to `false`, because aux param `{}` is missing", query_path_with_join.as_str(), &p );
603 SqlExpr::literal("false")
604 }
605 _ => on_expr,
606 };
607
608 join_expr.extend(on_expr);
609 join_expr.push_literal(") ");
610 }
611
612 Ok(join_expr)
613 }
614
615 fn build_where_clause<M>(
616 &mut self,
617 query: &Query<M>,
618 build_context: &mut BuildContext,
619 count_selection_only: bool,
620 result: &mut BuildResult,
621 ) -> Result<()> {
622 let p = [&self.aux_params, &query.aux_params];
623 let aux_params = ParameterMap::new(&p);
624
625 for token in &query.tokens {
626 match token {
627 QueryToken::Field(field) => {
628 if field.filter.is_none() {
630 continue;
631 }
632 let (query_path, field_name) = FieldPath::split_basename(&field.name);
633
634 if !Self::home_contains(&build_context.query_home_path, &query_path) {
636 continue;
637 }
638
639 if count_selection_only {
640 let root_mapper = self.root_mapper()?;
641 match root_mapper.selections.get("cnt") {
642 Some(selection) => {
643 let wildcard_path = format!("{}_*", field.name.as_str());
644 if !selection.contains(&field.name)
645 && !selection.contains(&wildcard_path)
646 {
647 continue;
648 }
649 }
650 None => continue,
651 }
652 }
653
654 let local_path = match query_path.localize_path(&build_context.query_home_path)
656 {
657 Some(l) => l,
658 None => return Ok(()),
659 };
660
661 let mapper_or_merge = self.mapper_or_merge_for_path(&local_path)?;
662
663 match mapper_or_merge {
664 MapperOrMerge::Mapper(mapper) => {
665 let mapped_field = mapper.fields.get(field_name).ok_or_else(|| {
666 SqlBuilderError::FieldMissing(field.name.to_string())
667 })?;
668
669 if let Some(role_expr) = &mapped_field.options.load_role_expr {
670 if !crate::role_validator::RoleValidator::is_valid(
671 &self.roles,
672 role_expr,
673 ) {
674 return Err(SqlBuilderError::RoleRequired(
675 role_expr.to_string(),
676 format!(
677 "field `{}`",
678 FieldPath::from(&build_context.query_home_path)
679 .append(&local_path)
680 .append(field_name)
681 .to_string(),
682 ),
683 )
684 .into());
685 }
686 }
687 let canonical_alias = self.canonical_alias(&query_path)?;
688
689 let p = [
690 &self.aux_params,
691 &query.aux_params,
692 &mapped_field.options.aux_params,
693 ];
694 let aux_params = ParameterMap::new(&p);
695
696 let handler = mapped_field
697 .options
698 .field_handler
699 .as_ref()
700 .unwrap_or(&mapper.field_handler);
701 let select_expr = handler
702 .build_select(mapped_field.expression.clone(), &aux_params)?
703 .unwrap_or_default();
704
705 if let Some(expr) = handler.build_filter(
707 select_expr,
708 field.filter.as_ref().unwrap(),
709 &aux_params,
710 )? {
711 let resolver = Resolver::new().with_self_alias(&canonical_alias);
712 let expr = resolver.resolve(&expr)?;
713 if !result.where_expr.is_empty()
714 && !result.where_expr.ends_with_literal("(")
715 {
716 result.where_expr.push_literal(
717 if field.concatenation == Concatenation::And {
718 " AND "
719 } else {
720 " OR "
721 },
722 );
723 }
724 result.where_expr.extend(expr);
725 }
726 }
727 MapperOrMerge::Merge(_merge_path) => {
728 }
730 }
731 }
732
733 QueryToken::Predicate(predicate) => {
734 let (query_path, basename) = FieldPath::split_basename(&predicate.name);
735
736 if !Self::home_contains(&build_context.query_home_path, &query_path) {
738 continue;
739 }
740
741 let local_path = match query_path.localize_path(&build_context.query_home_path)
742 {
743 Some(l) => l,
744 None => return Ok(()),
745 };
746
747 let mapper_or_merge = self.mapper_or_merge_for_path(&local_path)?;
748
749 match mapper_or_merge {
750 MapperOrMerge::Mapper(mapper) => {
751 let mapped_predicate =
752 mapper.predicates.get(basename).ok_or_else(|| {
753 SqlBuilderError::PredicateMissing(basename.to_string())
754 })?;
755
756 if count_selection_only && !mapped_predicate.options.count_filter {
757 continue;
758 }
759
760 if let Some(role) = &mapped_predicate.options.load_role_expr {
761 if !RoleValidator::is_valid(&self.roles, role) {
762 return Err(SqlBuilderError::RoleRequired(
763 role.to_string(),
764 format!(
765 "predicate `@{}`",
766 query_path
767 .append(&local_path)
768 .append(basename)
769 .to_string()
770 ),
771 )
772 .into());
773 }
774 }
775
776 let canonical_alias = self.canonical_alias(&local_path)?;
777
778 let resolver = Resolver::new()
779 .with_self_alias(&canonical_alias)
780 .with_arguments(&predicate.args)
781 .with_aux_params(&aux_params);
782
783 let handler = mapped_predicate
784 .options
785 .predicate_handler
786 .as_ref()
787 .unwrap_or(&mapper.predicate_handler);
788
789 if let Some(expr) = handler.build_predicate(
790 mapped_predicate.expression.clone(),
791 &predicate.args,
792 &aux_params,
793 )? {
794 if !result.where_expr.is_empty()
795 && !result.where_expr.ends_with_literal("(")
796 {
797 result.where_expr.push_literal(
798 if predicate.concatenation == Concatenation::And {
799 " AND "
800 } else {
801 " OR "
802 },
803 );
804 }
805 result.where_expr.extend(resolver.resolve(&expr)?);
806 if !mapped_predicate.options.on_aux_params.is_empty() {
807 for (i, a) in &mapped_predicate.options.on_aux_params {
808 if let Some(v) = predicate.args.get(*i as usize) {
809 build_context
811 .on_aux_params
812 .insert(a.clone(), v.clone());
813 } else {
814 tracing::warn!("Not enough predicate arguments to set on param `{}`.", &a);
815 }
816 }
817 }
818 }
819 }
820 MapperOrMerge::Merge(_merge_path) => {}
821 }
822 }
823 QueryToken::LeftBracket(concatenation) => {
824 if !result.where_expr.is_empty() && !result.where_expr.ends_with_literal("(") {
826 result
827 .where_expr
828 .push_literal(if concatenation == &Concatenation::And {
829 " AND "
830 } else {
831 " OR "
832 });
833 }
834 result.where_expr.push_literal("(");
835 }
836 QueryToken::RightBracket => {
837 if result.where_expr.ends_with_literal("(") {
839 result.where_expr.pop(); if result.where_expr.ends_with_literal(" AND ")
845 || result.where_expr.ends_with_literal(" OR ")
846 {
847 result.where_expr.pop();
848 }
849 } else {
850 result.where_expr.push_literal(")");
851 }
852 }
853 _ => {}
854 }
855 }
856 Ok(())
857 }
858
859 fn canonical_alias<'c>(&'c self, query_path: &'c FieldPath) -> Result<Cow<String>> {
860 let root_alias = &self.root_mapper()?.canonical_table_alias;
861
862 Ok(match query_path.is_empty() {
863 false => Cow::Owned(query_path.prepend(&root_alias).to_string()),
864 true => Cow::Borrowed(&root_alias),
865 })
866 }
867
868 fn preparse_query<M>(
869 &mut self,
870 query: &Query<M>,
871 build_context: &mut BuildContext,
872 result: &mut BuildResult,
873 ) -> Result<()> {
874 result.unmerged_home_paths = self.selection_from_query(query, build_context)?;
875 build_context.update_joins_from_selections();
876
877 Ok(())
878 }
879
880 fn build_order_clause(
881 &mut self,
882 query_aux_params: &HashMap<String, SqlArg>,
883 build_context: &mut BuildContext,
884 result: &mut BuildResult,
885 ) -> Result<()> {
886 let mut ordinals = Vec::with_capacity(build_context.ordering.len());
887 for o in build_context.ordering.keys() {
888 ordinals.push(o);
889 }
890 ordinals.sort();
891
892 for n in ordinals {
893 if let Some(orderings) = build_context.ordering.get(n) {
894 for (ord, local_path_with_basename) in orderings {
895 let (local_path, field_name) =
896 FieldPath::split_basename(local_path_with_basename);
897 if let Ok(mapper) = self.joined_mapper_for_local_path(&local_path) {
899 if let Some(role) = &mapper.load_role_expr {
900 if !RoleValidator::is_valid(&self.roles, role) {
901 return Err(SqlBuilderError::RoleRequired(
902 role.to_string(),
903 format!(
904 "field `{}`",
905 FieldPath::from(&build_context.query_home_path)
906 .append(&local_path)
907 .to_string(),
908 ),
909 )
910 .into());
911 }
912 }
913
914 let field_info = mapper
915 .field(field_name)
916 .ok_or_else(|| SqlBuilderError::FieldMissing(field_name.to_string()))?;
917
918 if let Some(load_role_expr) = &field_info.options.load_role_expr {
919 if !RoleValidator::is_valid(&self.roles, load_role_expr) {
920 return Err(SqlBuilderError::RoleRequired(
921 load_role_expr.to_string(),
922 format!(
923 "field `{}`",
924 FieldPath::from(&build_context.query_home_path)
925 .append(local_path_with_basename)
926 .to_string(),
927 ),
928 )
929 .into());
930 }
931 }
932
933 let p = [
934 &self.aux_params,
935 &field_info.options.aux_params,
936 query_aux_params,
937 ];
938 let aux_params = ParameterMap::new(&p);
939
940 let handler = field_info
941 .options
942 .field_handler
943 .as_ref()
944 .unwrap_or(&mapper.field_handler);
945 let select_expr =
946 handler.build_select(field_info.expression.clone(), &aux_params)?;
947 let canonical_alias = self.canonical_alias(&local_path)?;
948 if let Some(expr) = select_expr {
949 let resolver = Resolver::new().with_self_alias(&canonical_alias);
950 let expr = resolver.resolve(&expr)?;
951 result.order_expr.extend(expr);
952 result.order_expr.push_literal(match ord {
953 FieldOrder::Asc(_) => " ASC, ",
954 FieldOrder::Desc(_) => " DESC, ",
955 });
956 }
957 }
958 }
959 }
960 }
961 if !result.order_expr.is_empty() {
962 result.order_expr.pop_literals(2); }
964
965 Ok(())
966 }
967
968 fn build_select_clause<M>(
969 &mut self,
970 query: &Query<M>,
971 build_context: &mut BuildContext,
972 result: &mut BuildResult,
973 ) -> Result<()> {
974 self.resolve_select(&FieldPath::default(), query, build_context, result)?;
975 if result.select_expr.is_empty() {
976 result.select_expr.push_literal("1");
977 } else {
978 result.select_expr.pop_literals(2); }
980 if result.select_expr.is_empty() {
981 result.select_expr.push_literal("1");
982 } else {
983 result.select_expr.pop_literals(2); }
985
986 Ok(())
987 }
988
989 fn resolve_select<M>(
990 &self,
991 local_path: &FieldPath,
992 query: &Query<M>,
993 build_context: &mut BuildContext,
994 result: &mut BuildResult,
995 ) -> Result<()> {
996 let mapper = self.joined_mapper_for_local_path(&local_path)?;
997
998 let canonical_alias = self.canonical_alias(local_path)?;
999
1000 let path_selection = build_context
1001 .local_selected_paths
1002 .contains(local_path.as_str());
1003
1004 for deserialization_type in &mapper.deserialize_order {
1005 match deserialization_type {
1006 DeserializeType::Field(field_name) => {
1007 let local_field = if !local_path.is_empty() {
1008 Cow::Owned(format!("{}_{}", local_path.as_str(), field_name))
1009 } else {
1010 Cow::Borrowed(field_name)
1011 };
1012
1013 let mapped_field = mapper
1014 .field(field_name)
1015 .ok_or_else(|| SqlBuilderError::FieldMissing(field_name.to_string()))?;
1016
1017 let p = [
1018 &self.aux_params,
1019 &query.aux_params,
1020 &mapped_field.options.aux_params,
1021 ];
1022 let aux_params = ParameterMap::new(&p);
1023
1024 let role_valid = mapped_field
1025 .options
1026 .load_role_expr
1027 .as_ref()
1028 .map_or(true, |e| RoleValidator::is_valid(&self.roles, e));
1029
1030 if mapped_field.options.preselect {
1032 if !role_valid {
1033 let role_string = mapped_field
1034 .options
1035 .load_role_expr
1036 .as_ref()
1037 .map_or_else(|| String::new(), |e| e.to_string());
1038 return Err(SqlBuilderError::RoleRequired(
1039 role_string,
1040 format!(
1041 "field `{}`",
1042 FieldPath::from(&build_context.query_home_path)
1043 .append(&local_field)
1044 .to_string(),
1045 ),
1046 )
1047 .into());
1048 }
1049 let handler = mapped_field
1050 .options
1051 .field_handler
1052 .as_ref()
1053 .unwrap_or(&mapper.field_handler);
1054 let select_expr =
1055 handler.build_select(mapped_field.expression.clone(), &aux_params)?;
1056
1057 if let Some(expr) = select_expr {
1058 let resolver = Resolver::new().with_self_alias(&canonical_alias);
1059 let mut expr = resolver.resolve(&expr)?;
1060
1061 expr.push_literal(", ");
1062
1063 if local_path.is_empty()
1064 || build_context
1065 .local_joined_paths
1066 .contains(local_path.as_str())
1067 {
1068 result.select_expr.extend(expr);
1069 result.select_stream.push(Select::Preselect);
1070 } else {
1071 result.select_stream.push(Select::None);
1072 }
1073 } else {
1074 result.select_stream.push(Select::None);
1076 }
1077 }
1078 else if (path_selection && !mapped_field.options.skip_wildcard)
1080 || build_context
1081 .local_selected_fields
1082 .contains(local_field.as_ref())
1083 {
1084 if !role_valid
1086 && build_context
1087 .local_selected_fields
1088 .contains(local_field.as_ref())
1089 {
1090 let role_string = mapped_field
1091 .options
1092 .load_role_expr
1093 .as_ref()
1094 .map_or_else(|| String::new(), |e| e.to_string());
1095 return Err(SqlBuilderError::RoleRequired(
1096 role_string,
1097 format!(
1098 "field `{}`",
1099 FieldPath::from(&build_context.query_home_path)
1100 .append(&local_field)
1101 .to_string()
1102 ),
1103 )
1104 .into());
1105 }
1106
1107 if role_valid {
1108 let handler = mapped_field
1109 .options
1110 .field_handler
1111 .as_ref()
1112 .unwrap_or(&mapper.field_handler);
1113 let select_expr = handler
1114 .build_select(mapped_field.expression.clone(), &aux_params)?;
1115 if let Some(expr) = select_expr {
1116 match expr.first_aux_param() {
1118 Some(p) if path_selection => {
1119 let query_field =
1120 FieldPath::from(build_context.query_home_path.as_str())
1121 .append(local_field.as_str());
1122 tracing::info!("Unselecting field `{}` in struct for table `{}` because aux param `{}` is missing", query_field.as_str(), &mapper.table_name, &p );
1123 result.select_stream.push(Select::None);
1124 }
1125 _ => {
1126 let resolver =
1127 Resolver::new().with_self_alias(&canonical_alias);
1128 let expr = resolver.resolve(&expr)?;
1129 result.select_expr.extend(expr);
1130 result.select_expr.push_literal(", ");
1131 result.select_stream.push(Select::Query);
1132 result.column_counter += 1;
1133 }
1134 };
1135 } else {
1136 result.select_stream.push(Select::None);
1137 }
1138 } else {
1139 result.select_stream.push(Select::None);
1140 }
1141 } else {
1142 result.select_stream.push(Select::None);
1143 }
1144 }
1145 DeserializeType::Join(join_name) => {
1146 let mapped_join = mapper.join(join_name).ok_or_else(|| {
1147 SqlBuilderError::JoinMissing(
1148 join_name.to_string(),
1149 mapper.table_name.to_string(),
1150 )
1151 })?;
1152
1153 let local_join_path = local_path.append(join_name);
1154
1155 let role_valid = mapped_join
1156 .options
1157 .load_role_expr
1158 .as_ref()
1159 .map_or(true, |e| RoleValidator::is_valid(&self.roles, e));
1160
1161 let role_string = if let Some(e) = &mapped_join.options.load_role_expr {
1162 e.to_string()
1163 } else {
1164 String::from("")
1165 };
1166 if build_context
1168 .local_joined_paths
1169 .contains(&local_join_path.to_string())
1170 {
1171 if !role_valid {
1172 return Err(SqlBuilderError::RoleRequired(
1173 role_string,
1174 format!(
1175 "path `{}`",
1176 FieldPath::from(&build_context.query_home_path)
1177 .append(&local_join_path)
1178 .to_string(),
1179 ),
1180 )
1181 .into());
1182 }
1183 result.select_stream.push(Select::Query);
1185
1186 self.resolve_select(&local_join_path, query, build_context, result)?;
1188 } else if mapped_join.options.preselect {
1189 if !role_valid {
1190 return Err(SqlBuilderError::RoleRequired(
1191 role_string,
1192 format!(
1193 "path `{}`",
1194 FieldPath::from(&build_context.query_home_path)
1195 .append(&local_join_path)
1196 .to_string(),
1197 ),
1198 )
1199 .into());
1200 }
1201
1202 build_context
1204 .local_joined_paths
1205 .insert(local_join_path.to_string());
1206
1207 result.select_stream.push(Select::Preselect); self.resolve_select(&local_join_path, query, build_context, result)?;
1210 } else {
1211 result.select_stream.push(Select::None); }
1213 }
1214 DeserializeType::Merge(merge_name) => {
1215 let mapped_merge = mapper
1216 .merge(merge_name)
1217 .ok_or_else(|| SqlBuilderError::MergeMissing(merge_name.to_string()))?;
1218
1219 let query_field = FieldPath::from(build_context.query_home_path.as_str())
1220 .append(local_path.as_str())
1221 .append(merge_name.as_str());
1222
1223 if mapped_merge.options.preselect
1224 || query.contains_path_starts_with(&query_field)
1225 {
1226 if let Some(role_expr) = &mapped_merge.options.load_role_expr {
1227 if !RoleValidator::is_valid(&self.roles, role_expr) {
1228 return Err(SqlBuilderError::RoleRequired(
1229 role_expr.to_string(),
1230 format!("path `{}`", query_field.to_string(),),
1231 )
1232 .into());
1233 }
1234 }
1235
1236 result.unmerged_home_paths.insert(query_field.to_string());
1237 }
1238 }
1239 }
1240 }
1241
1242 Ok(())
1243 }
1244
1245 fn add_query_field(
1246 &self,
1247 query_field: &str,
1248 build_context: &mut BuildContext,
1249 unmerged_home_paths: &mut HashSet<String>,
1250 field_hidden: bool,
1251 ) -> Result<()> {
1252 let query_path = FieldPath::trim_basename(query_field);
1253 if !Self::home_contains(&build_context.query_home_path, &query_path) {
1254 return Ok(());
1255 }
1256 let local_path = match query_path.localize_path(&build_context.query_home_path) {
1257 Some(l) => l,
1258 None => return Ok(()),
1259 };
1260
1261 if let Some(local_merge_path) = self.next_merge_path(&local_path)? {
1262 unmerged_home_paths.insert(
1263 FieldPath::from(&build_context.query_home_path)
1264 .append(&local_merge_path)
1265 .to_string(),
1266 );
1267
1268 for path in FieldPath::from(&local_merge_path).step_up().skip(1) {
1269 build_context.local_joined_paths.insert(path.to_string());
1270 }
1271 } else {
1272 let query_field = FieldPath::from(&query_field);
1273 let local_field = match query_field.localize_path(&build_context.query_home_path) {
1274 Some(f) => f,
1275 None => return Ok(()),
1276 };
1277 if !field_hidden {
1278 build_context
1279 .local_selected_fields
1280 .insert(local_field.to_string());
1281 } else {
1282 for path in FieldPath::from(&local_field).step_up().skip(1) {
1284 build_context.local_joined_paths.insert(path.to_string());
1285 }
1286 }
1287 }
1288
1289 Ok(())
1290 }
1291
1292 fn resolve_custom_selection(
1293 &self,
1294 query_selection: &str,
1295 mut build_context: &mut BuildContext,
1296 mut unmerged_home_paths: &mut HashSet<String>,
1297 ) -> Result<()> {
1298 let (query_path, selection_name) = FieldPath::split_basename(query_selection);
1299 let mapper = self.mapper_for_query_path(&query_path)?;
1300 let selection = mapper
1301 .selections
1302 .get(selection_name)
1303 .ok_or_else(|| SqlBuilderError::SelectionMissing(selection_name.to_string()))?;
1304 for local_field_or_path in selection {
1305 if local_field_or_path.ends_with('*') || local_field_or_path.ends_with('_') {
1307 let query_path = FieldPath::from(query_path.as_str()).append(
1308 local_field_or_path
1309 .trim_end_matches('*')
1310 .trim_end_matches('_'),
1311 );
1312 if let Some(local_path) = query_path.localize_path(&build_context.query_home_path) {
1313 if let Some(merge_path) = self.next_merge_path(&local_path)? {
1314 unmerged_home_paths.insert(
1315 FieldPath::from(&build_context.query_home_path)
1316 .append(&merge_path)
1317 .to_string(),
1318 );
1319 } else {
1320 build_context
1321 .local_selected_paths
1322 .insert(local_path.to_string());
1323 }
1324 }
1325 } else {
1326 let query_field = FieldPath::from(query_path.as_str())
1327 .append(local_field_or_path)
1328 .to_string();
1329 let query_path = FieldPath::trim_basename(query_field.as_str());
1330 if let Some(local_path) = query_path.localize_path(&build_context.query_home_path) {
1331 if let Some(merge_path) = self.next_merge_path(&local_path)? {
1332 unmerged_home_paths.insert(
1333 FieldPath::from(&build_context.query_home_path)
1334 .append(&merge_path)
1335 .to_string(),
1336 );
1337 } else {
1338 self.add_query_field(
1339 query_field.as_str(),
1340 &mut build_context,
1341 &mut unmerged_home_paths,
1342 false,
1343 )?;
1344 }
1345 }
1346 }
1347 }
1348 Ok(())
1349 }
1350
1351 fn preparse_filter_joins<M>(
1352 &mut self,
1353 query: &Query<M>,
1354 build_context: &mut BuildContext,
1355 count_selection_only: bool,
1356 ) -> Result<()> {
1357 for token in &query.tokens {
1358 if let QueryToken::Field(field) = token {
1359 if field.filter.is_some() {
1360 let query_path = FieldPath::from(&field.name);
1361 if count_selection_only {
1362 let root_mapper = self.root_mapper()?;
1363 match root_mapper.selections.get("cnt") {
1364 Some(selection) => {
1365 let wildcard_path = format!("{}_*", field.name.as_str());
1366 if !selection.contains(&field.name)
1367 && !selection.contains(&wildcard_path)
1368 {
1369 continue;
1370 }
1371 }
1372 None => continue,
1373 }
1374 }
1375 if let Some(local_path_with_name) =
1376 query_path.localize_path(&build_context.query_home_path)
1377 {
1378 let field_path = FieldPath::trim_basename(local_path_with_name.as_str());
1379 if self.next_merge_path(&field_path)?.is_none() {
1380 for path in field_path.step_up() {
1381 build_context.local_joined_paths.insert(path.to_string());
1382 }
1383 }
1384 }
1385 }
1386 }
1387 }
1388 Ok(())
1389 }
1390 fn selection_from_query<M>(
1391 &mut self,
1392 query: &Query<M>,
1393 mut build_context: &mut BuildContext,
1394 ) -> Result<HashSet<String>> {
1395 let mut unmerged_home_paths = HashSet::new();
1396
1397 for token in &query.tokens {
1398 match token {
1399 QueryToken::Field(field) => {
1400 self.add_query_field(
1401 &field.name,
1402 &mut build_context,
1403 &mut unmerged_home_paths,
1404 field.hidden,
1405 )?;
1406 if let Some(o) = &field.order {
1407 let order = match o {
1408 FieldOrder::Asc(o) => o,
1409 FieldOrder::Desc(o) => o,
1410 };
1411 let query_path = FieldPath::from(&field.name);
1412 if let Some(local_path_with_name) =
1413 query_path.localize_path(&build_context.query_home_path)
1414 {
1415 build_context
1416 .ordering
1417 .entry(*order)
1418 .or_insert_with(Vec::new)
1419 .push((o.to_owned(), local_path_with_name.to_string()));
1420 }
1421 }
1422 }
1423 QueryToken::Wildcard(wildcard) => {
1424 let query_path = FieldPath::from(&wildcard.path.trim_end_matches('_'));
1426
1427 if let Some(local_path) =
1428 query_path.localize_path(&build_context.query_home_path)
1429 {
1430 if let Some(local_merge_path) = self.next_merge_path(&local_path)? {
1433 unmerged_home_paths.insert(
1435 FieldPath::from(&build_context.query_home_path)
1436 .append(&local_merge_path)
1437 .to_string(),
1438 );
1439 for path in FieldPath::from(&local_merge_path).step_up().skip(1) {
1440 build_context.local_joined_paths.insert(path.to_string());
1441 }
1442 } else {
1443 build_context
1444 .local_selected_paths
1445 .insert(local_path.to_string());
1446 }
1447 }
1449
1450 }
1452 QueryToken::Selection(selection) => {
1453 let (query_path, selection_name) = FieldPath::split_basename(&selection.name);
1454
1455 if let Some(local_path) =
1457 query_path.localize_path(&build_context.query_home_path)
1458 {
1459 if let Some(local_merge_path) = self.next_merge_path(&local_path)? {
1460 unmerged_home_paths.insert(
1462 FieldPath::from(&build_context.query_home_path)
1463 .append(&local_merge_path)
1464 .to_string(),
1465 );
1466 for path in FieldPath::from(&local_merge_path).step_up().skip(1) {
1467 build_context.local_joined_paths.insert(path.to_string());
1468 }
1469 } else {
1470 let mapper = self.joined_mapper_for_local_path(&local_path)?;
1471 match selection_name {
1472 "all" => {
1473 for deserialization_type in &mapper.deserialize_order {
1475 if let DeserializeType::Field(field_name) =
1476 deserialization_type
1477 {
1478 let f =
1480 mapper.fields.get(field_name).ok_or_else(|| {
1481 SqlBuilderError::FieldMissing(
1482 field_name.to_string(),
1483 )
1484 })?;
1485 if let Some(role_expr) = &f.options.load_role_expr {
1486 if !RoleValidator::is_valid(&self.roles, role_expr)
1487 {
1488 continue;
1489 }
1490 }
1491
1492 let query_field = FieldPath::from(
1493 build_context.query_home_path.as_str(),
1494 )
1495 .append(local_path.as_str())
1496 .append(field_name)
1497 .to_string();
1498 self.add_query_field(
1499 query_field.as_str(),
1500 &mut build_context,
1501 &mut unmerged_home_paths,
1502 false,
1503 )?;
1504 }
1505 }
1506 }
1507 "mut" => {
1508 for deserialization_type in &mapper.deserialize_order {
1511 if let DeserializeType::Field(field_name) =
1512 deserialization_type
1513 {
1514 let f =
1515 mapper.fields.get(field_name).ok_or_else(|| {
1516 SqlBuilderError::FieldMissing(
1517 field_name.to_string(),
1518 )
1519 })?;
1520 if let Some(role_expr) = &f.options.load_role_expr {
1522 if !RoleValidator::is_valid(&self.roles, role_expr)
1523 {
1524 continue;
1525 }
1526 }
1527 if let Some(role_expr) = &f.options.update_role_expr {
1529 if !RoleValidator::is_valid(&self.roles, role_expr)
1530 {
1531 continue;
1532 }
1533 }
1534 if !f.options.skip_mut && !f.options.key {
1535 let query_field = FieldPath::from(
1536 build_context.query_home_path.as_str(),
1537 )
1538 .append(local_path.as_str())
1539 .append(field_name)
1540 .to_string();
1541 self.add_query_field(
1542 query_field.as_str(),
1543 &mut build_context,
1544 &mut unmerged_home_paths,
1545 false,
1546 )?;
1547 }
1548 }
1549 }
1550 }
1551 "cnt" => {
1552 let selection = mapper.selections.get("cnt");
1553 if let Some(selection) = selection {
1554 for deserialization_type in &mapper.deserialize_order {
1557 if let DeserializeType::Field(query_field_name) =
1558 deserialization_type
1559 {
1560 let wildcard_path =
1561 format!("{}_*", query_field_name);
1562 if !selection.contains(&query_field_name)
1563 && !selection.contains(&wildcard_path)
1564 {
1565 continue;
1566 }
1567
1568 self.add_query_field(
1569 &query_field_name,
1570 &mut build_context,
1571 &mut unmerged_home_paths,
1572 false,
1573 )?;
1574 }
1575 }
1576 } else {
1577 for deserialization_type in &mapper.deserialize_order {
1579 if let DeserializeType::Field(field_name) =
1580 deserialization_type
1581 {
1582 let f = mapper.fields.get(field_name).ok_or_else(
1583 || {
1584 SqlBuilderError::FieldMissing(
1585 field_name.to_string(),
1586 )
1587 },
1588 )?;
1589 if f.options.key || f.options.preselect {
1590 let query_field = FieldPath::from(
1591 build_context.query_home_path.as_str(),
1592 )
1593 .append(local_path.as_str())
1594 .append(field_name)
1595 .to_string();
1596 self.add_query_field(
1597 query_field.as_str(),
1598 &mut build_context,
1599 &mut unmerged_home_paths,
1600 false,
1601 )?;
1602 }
1603 }
1604 }
1605 }
1606 }
1607 _ => {
1608 self.resolve_custom_selection(
1609 &selection.name,
1610 &mut build_context,
1611 &mut unmerged_home_paths,
1612 )?;
1613 }
1614 }
1615 }
1616 } else {
1617 if build_context
1622 .query_home_path
1623 .starts_with(query_path.as_str())
1624 {
1625 if selection_name != "cnt"
1626 && selection_name != "mut"
1627 && selection_name != "all"
1628 {
1629 self.resolve_custom_selection(
1630 &selection.name,
1631 &mut build_context,
1632 &mut unmerged_home_paths,
1633 )?;
1634 }
1635 }
1636 }
1637 }
1638 QueryToken::Predicate(predicate) => {
1639 let query_path = FieldPath::trim_basename(&predicate.name);
1640 if let Some(local_path) =
1641 query_path.localize_path(&build_context.query_home_path)
1642 {
1643 if self.joined_mapper_for_query_path(&local_path).is_ok() {
1645 for partial_local_path in FieldPath::from(&local_path).step_up() {
1646 build_context
1648 .local_joined_paths
1649 .insert(partial_local_path.to_string());
1650 }
1651 }
1652 }
1653 }
1654 _ => {}
1655 }
1656 }
1657
1658 Ok(unmerged_home_paths)
1659 }
1660
1661 fn root_mapper(&self) -> Result<&TableMapper> {
1662 self.table_mapper_registry
1663 .get(&self.home_mapper)
1664 .ok_or_else(|| ToqlError::MapperMissing(self.home_mapper.to_string()))
1665 }
1666 fn next_merge_path(&self, local_path: &FieldPath) -> Result<Option<String>> {
1667 let mut current_mapper = self
1668 .table_mapper_registry
1669 .get(&self.home_mapper)
1670 .ok_or_else(|| ToqlError::MapperMissing(self.home_mapper.to_string()))?;
1671
1672 for (mapper_name, merge_path) in local_path.children().zip(local_path.step_down()) {
1673 if current_mapper.merged_mapper(mapper_name.as_str()).is_some() {
1674 return Ok(Some(merge_path.to_string()));
1675 } else if let Some(joined_mapper_name) =
1676 current_mapper.joined_mapper(mapper_name.as_str())
1677 {
1678 let m = self
1679 .table_mapper_registry
1680 .get(&joined_mapper_name)
1681 .ok_or_else(|| ToqlError::MapperMissing(mapper_name.to_string()))?;
1682 current_mapper = m;
1683 } else {
1684 break;
1685 }
1686 }
1687 Ok(None)
1688 }
1689
1690 fn home_contains(home_path: &str, query_path: &FieldPath) -> bool {
1691 let r = match (home_path.is_empty(), query_path.is_empty()) {
1692 (true, true) => true,
1693 (false, true) => false,
1694 (true, false) => true,
1695 (false, false) => query_path.as_str().starts_with(home_path),
1696 };
1697
1698 r
1699 }
1700}