Skip to content

Commit c98eccd

Browse files
committed
style: fix trailing whitespace
- Removed trailing whitespace from plan_builder_utils.rs - All code formatting now clean per cargo fmt - No clippy warnings in modified files
1 parent 9a1a28c commit c98eccd

13 files changed

Lines changed: 400 additions & 182 deletions

File tree

src/clickhouse_query_generator/to_sql_query.rs

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use super::function_translator::{get_ch_function_name, CH_PASSTHROUGH_PREFIX};
2323
/// TASK-LOCAL RENDER CONTEXT: Per-async-task storage for query rendering
2424
/// Each Axum async task (HTTP request) gets its own isolated context.
2525
/// Multiple concurrent queries on same OS thread have zero interference.
26-
///
26+
///
2727
/// Why task_local instead of thread_local:
2828
/// - thread_local: Shared by all async tasks on same OS thread (UNSAFE for concurrent queries)
2929
/// - task_local: Each async task gets isolated storage (SAFE)
@@ -46,9 +46,9 @@ fn get_cte_column_from_context(cte_alias: &str, property: &str) -> Option<String
4646
// task_local! uses sync accessors, not .with()
4747
RENDER_CONTEXT_CTE_REGISTRY
4848
.try_with(|ctx| {
49-
ctx.borrow().as_ref().and_then(|registry| {
50-
registry.lookup(cte_alias, property)
51-
})
49+
ctx.borrow()
50+
.as_ref()
51+
.and_then(|registry| registry.lookup(cte_alias, property))
5252
})
5353
.ok()
5454
.flatten()
@@ -80,9 +80,7 @@ fn clear_render_context_cte_registry() {
8080
// RELATIONSHIP COLUMNS CONTEXT (for IS NULL checks on relationship aliases)
8181
// ============================================================================
8282

83-
fn set_render_context_relationship_columns(
84-
columns: HashMap<String, (String, String)>,
85-
) {
83+
fn set_render_context_relationship_columns(columns: HashMap<String, (String, String)>) {
8684
let _ = RENDER_CONTEXT_RELATIONSHIP_COLUMNS.try_with(|ctx| {
8785
ctx.borrow_mut().replace(columns);
8886
});
@@ -109,9 +107,7 @@ fn clear_render_context_relationship_columns() {
109107
// CTE PROPERTY MAPPINGS CONTEXT (for CTE property → column resolution)
110108
// ============================================================================
111109

112-
fn set_render_context_cte_property_mappings(
113-
mappings: HashMap<String, HashMap<String, String>>,
114-
) {
110+
fn set_render_context_cte_property_mappings(mappings: HashMap<String, HashMap<String, String>>) {
115111
let _ = RENDER_CONTEXT_CTE_PROPERTY_MAPPINGS.try_with(|ctx| {
116112
ctx.borrow_mut().replace(mappings);
117113
});
@@ -189,7 +185,7 @@ fn clear_all_render_contexts() {
189185
/// TASK-LOCAL RENDER CONTEXT: Per-async-task storage for rendering state
190186
/// Each Axum async task (HTTP request) gets its own isolated context.
191187
/// Multiple concurrent queries on same OS thread have zero interference.
192-
///
188+
///
193189
/// Lifecycle:
194190
/// 1. At render_to_sql() entry: Set all three contexts
195191
/// 2. During rendering: Access contexts for property/column lookups
@@ -373,7 +369,7 @@ fn build_multi_type_vlp_aliases(plan: &RenderPlan) -> HashMap<String, String> {
373369
fn populate_cte_property_mappings(plan: &RenderPlan) {
374370
let cte_mappings = build_cte_property_mappings(plan);
375371
let multi_type_aliases = build_multi_type_vlp_aliases(plan);
376-
372+
377373
set_render_context_cte_property_mappings(cte_mappings);
378374
set_render_context_multi_type_vlp_aliases(multi_type_aliases);
379375
}
@@ -622,7 +618,9 @@ fn derive_cypher_property_name(db_column: &str) -> String {
622618

623619
/// Extract fixed path information from a RenderPlan by analyzing SELECT items and JOINs
624620
/// Returns FixedPathMetadata if the plan contains a path function call that can be resolved
625-
fn extract_fixed_path_info_from_plan(plan: &RenderPlan) -> Option<crate::render_plan::FixedPathMetadata> {
621+
fn extract_fixed_path_info_from_plan(
622+
plan: &RenderPlan,
623+
) -> Option<crate::render_plan::FixedPathMetadata> {
626624
// Look for path function calls in SELECT items
627625
for item in &plan.select.items {
628626
if let Some(path_var) = find_path_function_argument(&item.expression) {
@@ -632,14 +630,14 @@ fn extract_fixed_path_info_from_plan(plan: &RenderPlan) -> Option<crate::render_
632630
// For a path (a)-[:T1]->(b)-[:T2]->(c), we have 4 JOINs = 2 hops
633631
// Formula: hops = JOINs / 2 (integer division)
634632
let hop_count = plan.joins.0.len() as u32 / 2;
635-
633+
636634
log::info!(
637635
"🔧 Detected fixed path: path_variable={}, hop_count={} (from {} JOINs)",
638636
path_var,
639637
hop_count,
640638
plan.joins.0.len()
641639
);
642-
640+
643641
return Some(crate::render_plan::FixedPathMetadata {
644642
path_variable: path_var,
645643
hop_count,
@@ -648,7 +646,7 @@ fn extract_fixed_path_info_from_plan(plan: &RenderPlan) -> Option<crate::render_
648646
});
649647
}
650648
}
651-
649+
652650
// Also check GROUP BY and ORDER BY expressions
653651
for expr in &plan.group_by.0 {
654652
if let Some(path_var) = find_path_function_argument(expr) {
@@ -661,7 +659,7 @@ fn extract_fixed_path_info_from_plan(plan: &RenderPlan) -> Option<crate::render_
661659
});
662660
}
663661
}
664-
662+
665663
for item in &plan.order_by.0 {
666664
if let Some(path_var) = find_path_function_argument(&item.expression) {
667665
let hop_count = plan.joins.0.len() as u32 / 2;
@@ -673,7 +671,7 @@ fn extract_fixed_path_info_from_plan(plan: &RenderPlan) -> Option<crate::render_
673671
});
674672
}
675673
}
676-
674+
677675
None
678676
}
679677

@@ -683,14 +681,17 @@ fn find_path_function_argument(expr: &RenderExpr) -> Option<String> {
683681
match expr {
684682
RenderExpr::ScalarFnCall(func) => {
685683
// Check for path functions
686-
if matches!(func.name.to_lowercase().as_str(), "length" | "nodes" | "relationships") {
684+
if matches!(
685+
func.name.to_lowercase().as_str(),
686+
"length" | "nodes" | "relationships"
687+
) {
687688
if func.args.len() == 1 {
688689
if let RenderExpr::TableAlias(alias) = &func.args[0] {
689690
return Some(alias.0.clone());
690691
}
691692
}
692693
}
693-
694+
694695
// Recursively check arguments
695696
for arg in &func.args {
696697
if let Some(var) = find_path_function_argument(arg) {
@@ -699,7 +700,7 @@ fn find_path_function_argument(expr: &RenderExpr) -> Option<String> {
699700
}
700701
None
701702
}
702-
703+
703704
RenderExpr::OperatorApplicationExp(op) => {
704705
for operand in &op.operands {
705706
if let Some(var) = find_path_function_argument(operand) {
@@ -708,7 +709,7 @@ fn find_path_function_argument(expr: &RenderExpr) -> Option<String> {
708709
}
709710
None
710711
}
711-
712+
712713
RenderExpr::AggregateFnCall(agg) => {
713714
for arg in &agg.args {
714715
if let Some(var) = find_path_function_argument(arg) {
@@ -717,7 +718,7 @@ fn find_path_function_argument(expr: &RenderExpr) -> Option<String> {
717718
}
718719
None
719720
}
720-
721+
721722
_ => None,
722723
}
723724
}
@@ -750,15 +751,22 @@ fn rewrite_fixed_path_functions(mut plan: RenderPlan) -> RenderPlan {
750751
}
751752

752753
// Also rewrite GROUP BY expressions
753-
log::info!("🔧 Fixed path GROUP BY rewriting: {} items", plan.group_by.0.len());
754+
log::info!(
755+
"🔧 Fixed path GROUP BY rewriting: {} items",
756+
plan.group_by.0.len()
757+
);
754758
for group_expr in &mut plan.group_by.0 {
755759
*group_expr = rewrite_expr_for_fixed_path(group_expr, &path_var, hop_count);
756760
}
757761

758762
// Also rewrite ORDER BY expressions
759-
log::info!("🔧 Fixed path ORDER BY rewriting: {} items", plan.order_by.0.len());
763+
log::info!(
764+
"🔧 Fixed path ORDER BY rewriting: {} items",
765+
plan.order_by.0.len()
766+
);
760767
for order_item in &mut plan.order_by.0 {
761-
order_item.expression = rewrite_expr_for_fixed_path(&order_item.expression, &path_var, hop_count);
768+
order_item.expression =
769+
rewrite_expr_for_fixed_path(&order_item.expression, &path_var, hop_count);
762770
}
763771
}
764772

@@ -1167,31 +1175,30 @@ impl SelectItems {
11671175
// 🔧 SCALAR FIX: ColumnAlias never gets `.*` expansion - it's a scalar column reference
11681176
// This handles: WITH n.email as group_key ... RETURN group_key
11691177
// where group_key is a scalar column, not a node/table
1170-
let rendered_expr =
1171-
if let RenderExpr::ColumnAlias(_) = &item.expression {
1172-
// ColumnAlias is always rendered as-is (scalar reference)
1173-
// No wildcard expansion: group_key stays group_key, not group_key.*
1174-
item.expression.to_sql()
1175-
} else if let RenderExpr::TableAlias(TableAlias(alias_name)) = &item.expression {
1176-
if let Some(col_alias) = &item.col_alias {
1177-
if alias_name == &col_alias.0 {
1178-
// Check if this is an UNWIND alias - don't use `.*` for scalars
1179-
if unwind_aliases.contains(alias_name) {
1180-
// UNWIND alias: render as just the alias (scalar value)
1181-
alias_name.clone()
1182-
} else {
1183-
// Path/table alias: use `.*` expansion
1184-
format!("{}.*", alias_name)
1185-
}
1178+
let rendered_expr = if let RenderExpr::ColumnAlias(_) = &item.expression {
1179+
// ColumnAlias is always rendered as-is (scalar reference)
1180+
// No wildcard expansion: group_key stays group_key, not group_key.*
1181+
item.expression.to_sql()
1182+
} else if let RenderExpr::TableAlias(TableAlias(alias_name)) = &item.expression {
1183+
if let Some(col_alias) = &item.col_alias {
1184+
if alias_name == &col_alias.0 {
1185+
// Check if this is an UNWIND alias - don't use `.*` for scalars
1186+
if unwind_aliases.contains(alias_name) {
1187+
// UNWIND alias: render as just the alias (scalar value)
1188+
alias_name.clone()
11861189
} else {
1187-
item.expression.to_sql()
1190+
// Path/table alias: use `.*` expansion
1191+
format!("{}.*", alias_name)
11881192
}
11891193
} else {
11901194
item.expression.to_sql()
11911195
}
11921196
} else {
11931197
item.expression.to_sql()
1194-
};
1198+
}
1199+
} else {
1200+
item.expression.to_sql()
1201+
};
11951202

11961203
sql.push_str(&rendered_expr);
11971204

@@ -2055,10 +2062,18 @@ impl RenderExpr {
20552062
if is_multi_type_vlp_alias_from_context(&table_alias.0) {
20562063
log::info!("🎯 Found '{}' in multi-type VLP aliases!", table_alias.0);
20572064
// Properties like end_type, end_id, hop_count, path_relationships are direct CTE columns
2058-
if col_name == VLP_START_ID_COLUMN || col_name == VLP_END_ID_COLUMN
2059-
|| matches!(col_name, "end_type" | "end_properties" | "hop_count" | "path_relationships")
2065+
if col_name == VLP_START_ID_COLUMN
2066+
|| col_name == VLP_END_ID_COLUMN
2067+
|| matches!(
2068+
col_name,
2069+
"end_type" | "end_properties" | "hop_count" | "path_relationships"
2070+
)
20602071
{
2061-
log::info!("🎯 Multi-type VLP CTE column: {}.{}", table_alias.0, col_name);
2072+
log::info!(
2073+
"🎯 Multi-type VLP CTE column: {}.{}",
2074+
table_alias.0,
2075+
col_name
2076+
);
20622077
return format!("{}.{}", table_alias.0, col_name);
20632078
} else {
20642079
// Regular properties need JSON extraction from end_properties
@@ -2157,7 +2172,9 @@ impl RenderExpr {
21572172

21582173
// Look up the actual column name from the JOIN metadata (populated during rendering)
21592174
// This ensures we use the CORRECT column for the SPECIFIC relationship table
2160-
if let Some((from_id, _to_id)) = get_relationship_columns_from_context(table_alias) {
2175+
if let Some((from_id, _to_id)) =
2176+
get_relationship_columns_from_context(table_alias)
2177+
{
21612178
// Use from_id - any ID column works since LEFT JOIN makes all NULL together
21622179
let id_sql = format!("{}.{}", table_alias, from_id);
21632180
return format!("{} {}", id_sql, op_str);

src/query_planner/analyzer/schema_inference.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ impl SchemaInference {
5454
// Get inferred label from TableCtx
5555
match plan_ctx.get_table_ctx(&graph_node.alias) {
5656
Ok(table_ctx) => {
57-
log::debug!("SchemaInference: Found table_ctx for node '{}' with labels {:?}", graph_node.alias, table_ctx.get_labels());
57+
log::debug!(
58+
"SchemaInference: Found table_ctx for node '{}' with labels {:?}",
59+
graph_node.alias,
60+
table_ctx.get_labels()
61+
);
5862
if let Some(labels) = table_ctx.get_labels() {
5963
if !labels.is_empty() && labels[0] != "$any" {
6064
let label = &labels[0];
@@ -99,11 +103,18 @@ impl SchemaInference {
99103
log::debug!("SchemaInference: Node '{}' has no labels or $any label, skipping ViewScan creation", graph_node.alias);
100104
}
101105
} else {
102-
log::debug!("SchemaInference: No labels found for node '{}' in table_ctx", graph_node.alias);
106+
log::debug!(
107+
"SchemaInference: No labels found for node '{}' in table_ctx",
108+
graph_node.alias
109+
);
103110
}
104111
}
105112
Err(e) => {
106-
log::debug!("SchemaInference: No table_ctx found for node '{}': {:?}", graph_node.alias, e);
113+
log::debug!(
114+
"SchemaInference: No table_ctx found for node '{}': {:?}",
115+
graph_node.alias,
116+
e
117+
);
107118
}
108119
}
109120
}

src/query_planner/analyzer/variable_resolver.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl ScopeContext {
177177
pub struct VariableResolver {
178178
/// Counter for generating unique CTE names
179179
cte_counter: std::cell::RefCell<usize>,
180-
180+
181181
/// Collected alias sources during analysis: exported_alias → (source_alias, cte_name)
182182
/// These are registered into PlanCtx after resolution completes
183183
alias_sources: std::cell::RefCell<HashMap<String, (String, String)>>,
@@ -355,14 +355,16 @@ impl VariableResolver {
355355
for (i, item) in resolved_items.iter().enumerate() {
356356
if i < wc.exported_aliases.len() {
357357
let exported_alias = &wc.exported_aliases[i];
358-
358+
359359
// Try to extract the source alias from the expression
360360
// Common case: WITH u AS person - expression is TableAlias("u")
361361
if let LogicalExpr::TableAlias(source_alias_ta) = &item.expression {
362362
let source_alias_str = source_alias_ta.0.clone();
363363
log::info!(
364364
"🔍 VariableResolver: Collecting alias source: {} ← ({}, {})",
365-
exported_alias, source_alias_str, cte_name
365+
exported_alias,
366+
source_alias_str,
367+
cte_name
366368
);
367369
self.alias_sources.borrow_mut().insert(
368370
exported_alias.clone(),
@@ -1224,7 +1226,9 @@ impl AnalyzerPass for VariableResolver {
12241226
for (exported_alias, (source_alias, cte_name)) in alias_sources.iter() {
12251227
log::info!(
12261228
"🔍 VariableResolver: Registering alias source {} ← ({}, {})",
1227-
exported_alias, source_alias, cte_name
1229+
exported_alias,
1230+
source_alias,
1231+
cte_name
12281232
);
12291233
plan_ctx.register_cte_alias_source(
12301234
exported_alias.clone(),

src/render_plan/cte_manager/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub enum CteError {
4848
}
4949

5050
/// Metadata for a column in a generated CTE
51-
///
51+
///
5252
/// This provides complete information for mapping Cypher property accesses to CTE columns
5353
/// WITHOUT heuristics or underscore splitting.
5454
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]

src/render_plan/join_builder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,7 @@ impl JoinBuilder for LogicalPlan {
18731873
"🔧 DEBUG: About to push JOIN 2 (end node): {} AS {}",
18741874
end_table, graph_rel.right_connection
18751875
);
1876-
1876+
18771877
// DENORMALIZED EDGE CHECK: Only add JOIN 2 if target node is a different table
18781878
// For denormalized edges (e.g., AUTHORED with posts_bench as both edge+node),
18791879
// end_table == rel_table, so we should NOT join the table again
@@ -1896,7 +1896,8 @@ impl JoinBuilder for LogicalPlan {
18961896
);
18971897
log::info!(
18981898
"✓ Denormalized edge for {}: table '{}' serves as both edge and node",
1899-
graph_rel.alias, rel_table
1899+
graph_rel.alias,
1900+
rel_table
19001901
);
19011902
}
19021903

src/render_plan/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub struct RenderPlan {
8585
pub fixed_path_info: Option<FixedPathMetadata>,
8686
/// Per-query CTE column registry - maps (alias, property) to CTE output column name
8787
/// Used during SQL rendering to resolve property accesses from WITH clauses
88-
#[serde(skip)] // Don't serialize, recreate during rendering
88+
#[serde(skip)] // Don't serialize, recreate during rendering
8989
pub cte_column_registry: CteColumnRegistry,
9090
}
9191

0 commit comments

Comments
 (0)