@@ -445,13 +445,13 @@ fn rewrite_vlp_select_aliases(mut plan: RenderPlan) -> RenderPlan {
445445 // FROM is None — likely a Union shell where branches have their own FROM.
446446 // Check if any Union branch FROM uses the VLP CTE. If not, the VLP CTE
447447 // is consumed by a WITH CTE (not by the main query) — skip rewriting.
448- let any_branch_uses_vlp = plan. union . 0 . as_ref ( ) . map_or ( false , |union| {
448+ let any_branch_uses_vlp = plan. union . 0 . as_ref ( ) . is_some_and ( |union| {
449449 union. input . iter ( ) . any ( |branch| {
450450 branch
451451 . from
452452 . 0
453453 . as_ref ( )
454- . map_or ( false , |f| f. name . starts_with ( "vlp_" ) )
454+ . is_some_and ( |f| f. name . starts_with ( "vlp_" ) )
455455 } )
456456 } ) ;
457457 if !any_branch_uses_vlp {
@@ -954,6 +954,32 @@ pub(crate) fn rewrite_expr_for_vlp(
954954 ) ) ) ;
955955 }
956956 }
957+ // Handle bare path variable: p -> tuple(t.path_nodes, t.path_relationships, t.hop_count)
958+ // When RETURN p is used for a path variable, expand it to a tuple of path components
959+ if path_variable. as_ref ( ) == Some ( & alias. 0 ) {
960+ log:: info!(
961+ "VLP path variable expansion: {} -> tuple({}.path_nodes, ...)" ,
962+ alias. 0 ,
963+ VLP_CTE_FROM_ALIAS ,
964+ ) ;
965+ return RenderExpr :: ScalarFnCall ( ScalarFnCall {
966+ name : "tuple" . to_string ( ) ,
967+ args : vec ! [
968+ RenderExpr :: Column ( Column ( PropertyValue :: Column ( format!(
969+ "{}.path_nodes" ,
970+ VLP_CTE_FROM_ALIAS
971+ ) ) ) ) ,
972+ RenderExpr :: Column ( Column ( PropertyValue :: Column ( format!(
973+ "{}.path_relationships" ,
974+ VLP_CTE_FROM_ALIAS
975+ ) ) ) ) ,
976+ RenderExpr :: Column ( Column ( PropertyValue :: Column ( format!(
977+ "{}.hop_count" ,
978+ VLP_CTE_FROM_ALIAS
979+ ) ) ) ) ,
980+ ] ,
981+ } ) ;
982+ }
957983 expr. clone ( )
958984 }
959985
@@ -1138,34 +1164,6 @@ pub(crate) fn rewrite_expr_for_vlp(
11381164 . collect ( ) ,
11391165 } ) ,
11401166
1141- // Handle bare path variable: p → tuple(t.path_nodes, t.path_relationships, t.hop_count)
1142- // When RETURN p is used for a path variable, expand it to a tuple of path components
1143- RenderExpr :: TableAlias ( alias) if path_variable. as_ref ( ) == Some ( & alias. 0 ) => {
1144- log:: info!(
1145- "🔧 VLP path variable expansion: {} → tuple({}.path_nodes, ...)" ,
1146- alias. 0 ,
1147- VLP_CTE_FROM_ALIAS ,
1148- ) ;
1149- // Expand to tuple of path components using VLP_CTE_FROM_ALIAS constant
1150- RenderExpr :: ScalarFnCall ( ScalarFnCall {
1151- name : "tuple" . to_string ( ) ,
1152- args : vec ! [
1153- RenderExpr :: Column ( Column ( PropertyValue :: Column ( format!(
1154- "{}.path_nodes" ,
1155- VLP_CTE_FROM_ALIAS
1156- ) ) ) ) ,
1157- RenderExpr :: Column ( Column ( PropertyValue :: Column ( format!(
1158- "{}.path_relationships" ,
1159- VLP_CTE_FROM_ALIAS
1160- ) ) ) ) ,
1161- RenderExpr :: Column ( Column ( PropertyValue :: Column ( format!(
1162- "{}.hop_count" ,
1163- VLP_CTE_FROM_ALIAS
1164- ) ) ) ) ,
1165- ] ,
1166- } )
1167- }
1168-
11691167 RenderExpr :: ColumnAlias ( ColumnAlias ( alias_str) )
11701168 if path_variable. as_ref ( ) == Some ( alias_str) =>
11711169 {
@@ -2336,7 +2334,7 @@ fn flatten_all_ctes(plan: &mut RenderPlan) {
23362334 plan. ctes . 0 = collected;
23372335}
23382336
2339- pub fn render_plan_to_sql ( mut plan : RenderPlan , max_cte_depth : u32 ) -> String {
2337+ pub fn render_plan_to_sql ( mut plan : RenderPlan , _max_cte_depth : u32 ) -> String {
23402338 // STEP 0: Flatten ALL CTEs to top level in dependency order.
23412339 // CTEs are always a flat, linear chain — never nested inside other CTEs or union branches.
23422340 flatten_all_ctes ( & mut plan) ;
@@ -2547,7 +2545,7 @@ pub fn render_plan_to_sql(mut plan: RenderPlan, max_cte_depth: u32) -> String {
25472545 if let Some ( _union) = & plan. union . 0 {
25482546 if has_aggregation {
25492547 // Collect aggregate aliases to detect dependent order columns
2550- let agg_aliases : std:: collections:: HashSet < String > = plan
2548+ let _agg_aliases : std:: collections:: HashSet < String > = plan
25512549 . select
25522550 . items
25532551 . iter ( )
@@ -3536,8 +3534,7 @@ impl RenderExpr {
35363534 // CTE column names use p{N}_ prefix (e.g., p6_friend_lastName).
35373535 // These are output aliases after GROUP BY/UNION and should NOT get
35383536 // a heuristic table prefix.
3539- if raw_value. starts_with ( 'p' ) {
3540- let rest = & raw_value[ 1 ..] ;
3537+ if let Some ( rest) = raw_value. strip_prefix ( 'p' ) {
35413538 if let Some ( pos) = rest. find ( '_' ) {
35423539 if pos > 0 && rest[ ..pos] . chars ( ) . all ( |c| c. is_ascii_digit ( ) ) {
35433540 return raw_value. to_string ( ) ;
0 commit comments