@@ -356,22 +356,15 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> {
356356 }
357357
358358 fn add_condition ( & mut self , condition : Condition , table : Option < & TableReference > ) {
359- let conditions = table
359+ table
360360 . and_then ( |table| {
361- self . statement . joins . iter_mut ( ) . find_map ( |join| match join {
362- // If a table is provided and we have a join on that table, we add the condition
363- // to the
364- JoinExpression :: Old {
365- from,
366- additional_conditions,
367- ..
368- } if * from. reference_table ( ) == * table => Some ( additional_conditions) ,
369- JoinExpression :: Old { .. } => None ,
361+ // If a table is provided and we have a join on that table, we add the condition
362+ self . statement . joins . iter_mut ( ) . find_map ( |join| {
363+ ( * table == * join. from . reference_table ( ) ) . then_some ( & mut join. conditions )
370364 } )
371365 } )
372- . unwrap_or ( & mut self . statement . where_expression . conditions ) ;
373-
374- conditions. push ( condition) ;
366+ . unwrap_or ( & mut self . statement . where_expression . conditions )
367+ . push ( condition) ;
375368 }
376369
377370 /// Adds a new path to the selection which can be used as cursor.
@@ -572,11 +565,7 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> {
572565 } ;
573566
574567 if let Some ( last_join) = self . statement . joins . last_mut ( ) {
575- let JoinExpression :: Old {
576- from : last_join_from,
577- ..
578- } = last_join;
579- let last_reference_table = last_join_from. reference_table ( ) ;
568+ let last_reference_table = last_join. from . reference_table ( ) ;
580569 ensure ! (
581570 last_reference_table. name == TableName :: from( Table :: DataTypeEmbeddings )
582571 || last_reference_table. name
@@ -628,7 +617,7 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> {
628617 | Table :: Reference ( _) => unreachable ! ( ) ,
629618 } ;
630619
631- * last_join_from = JoinFrom :: SelectStatement {
620+ last_join . from = JoinFrom :: SelectStatement {
632621 statement : Box :: new ( SelectStatement {
633622 with : WithExpression :: default ( ) ,
634623 distinct : vec ! [ ] ,
@@ -1097,76 +1086,85 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> {
10971086
10981087 let mut is_outer_join_chain = false ;
10991088 for relation in path. relations ( ) {
1100- let foreign_key_join = relation. joins ( ) ;
1101- for foreign_key_reference in foreign_key_join {
1102- let mut join_expression = JoinExpression :: from_foreign_key (
1103- foreign_key_reference,
1104- current_table. alias . unwrap_or_default ( ) ,
1105- Alias {
1106- condition_index : self . artifacts . condition_index ,
1107- chain_depth : current_table. alias . unwrap_or_default ( ) . chain_depth + 1 ,
1108- number : 0 ,
1109- } ,
1110- ) ;
1111-
1112- let JoinExpression :: Old {
1113- join : join_expression_type,
1114- from : join_expression_from,
1115- on : join_expression_on,
1116- on_alias : join_expression_on_alias,
1117- ..
1118- } = & mut join_expression;
1119- let join_expression_table = join_expression_from. reference_table_mut ( ) ;
1120-
1121- if is_outer_join_chain {
1122- * join_expression_type = JoinType :: LeftOuter ;
1123- } else if * join_expression_type != JoinType :: Inner {
1124- is_outer_join_chain = true ;
1089+ for foreign_key_reference in relation. joins ( ) {
1090+ let join_type = if is_outer_join_chain {
1091+ JoinType :: LeftOuter
11251092 } else {
1126- // Join is Inner type, keep as-is
1127- }
1093+ let join_type = foreign_key_reference. join_type ( ) ;
1094+ if join_type != JoinType :: Inner {
1095+ is_outer_join_chain = true ;
1096+ }
1097+ join_type
1098+ } ;
1099+
1100+ let mut join_table = foreign_key_reference. table ( ) . aliased ( Alias {
1101+ condition_index : self . artifacts . condition_index ,
1102+ chain_depth : current_table. alias . unwrap_or_default ( ) . chain_depth + 1 ,
1103+ number : 0 ,
1104+ } ) ;
1105+ let mut conditions =
1106+ foreign_key_reference. conditions ( current_table. alias , join_table. alias ) ;
11281107
11291108 let mut found = false ;
1109+ let mut max_number = 0 ;
1110+
11301111 for existing in & self . statement . joins {
1131- let JoinExpression :: Old {
1132- from : existing_from,
1133- on : existing_on,
1134- on_alias : existing_on_alias,
1135- ..
1136- } = existing;
1137- let existing_table = existing_from. reference_table ( ) ;
1138-
1139- if existing_table == join_expression_table {
1112+ let existing_table = existing. from . reference_table ( ) ;
1113+
1114+ // Check for exact match to reuse existing join
1115+ if * existing_table == join_table {
11401116 // We only need to check the join conditions, not the join type or
11411117 // additional conditions. This is enough to reuse an existing join
11421118 // statement.
1143- if existing_on == join_expression_on
1144- && existing_on_alias == join_expression_on_alias
1145- {
1146- // We already have a join statement for this column, so we can reuse it.
1119+ if existing. conditions . starts_with ( & conditions) {
1120+ // We already have a join statement for this column, so we can reuse
1121+ // it.
11471122 current_table = Cow :: Borrowed ( existing_table) ;
11481123 found = true ;
11491124 break ;
11501125 }
1151- // We already have a join statement for this table, but it's on a different
1152- // column. We need to create a new join statement later on with a new,
1153- // unique alias.
1154- join_expression_table. alias . get_or_insert_default ( ) . number += 1 ;
1126+ }
1127+
1128+ // Track maximum number for joins with same table name and alias prefix
1129+ if let Some ( existing_alias) = existing_table. alias
1130+ && join_table. name == existing_table. name
1131+ && join_table
1132+ . alias
1133+ . map ( |alias| ( alias. condition_index , alias. chain_depth ) )
1134+ == existing_table
1135+ . alias
1136+ . map ( |alias| ( alias. condition_index , alias. chain_depth ) )
1137+ {
1138+ max_number = max_number. max ( existing_alias. number + 1 ) ;
11551139 }
11561140 }
11571141
1142+ // If we didn't find an exact match but found alias conflicts, update the alias
11581143 if !found {
1159- // We don't have a join statement for this column yet, so we need to create one.
1160- current_table = Cow :: Owned ( join_expression_table. clone ( ) ) ;
1161- let current_alias = current_table. alias . unwrap_or_default ( ) ;
1162- self . statement . joins . push ( join_expression) ;
1163-
1164- for condition in relation. additional_conditions ( & current_table) {
1165- self . add_condition ( condition, Some ( & current_table) ) ;
1144+ if max_number > 0 {
1145+ join_table. alias . get_or_insert_default ( ) . number = max_number;
1146+ // Recalculate conditions with the updated alias
1147+ conditions =
1148+ foreign_key_reference. conditions ( current_table. alias , join_table. alias ) ;
11661149 }
11671150
1151+ // We don't have a join statement for this column yet, so we need to create one.
1152+ current_table = Cow :: Owned ( join_table. clone ( ) ) ;
1153+ conditions. extend ( relation. additional_conditions ( & join_table) ) ;
1154+ self . statement . joins . push ( JoinExpression {
1155+ join : join_type,
1156+ from : JoinFrom :: Table {
1157+ table : TableReference {
1158+ alias : None ,
1159+ ..join_table. clone ( )
1160+ } ,
1161+ alias : Some ( join_table) ,
1162+ } ,
1163+ conditions,
1164+ } ) ;
1165+
11681166 if let Some ( hook) = self . table_hooks . get ( & current_table. name ) {
1169- hook ( self , current_alias ) ;
1167+ hook ( self , current_table . alias . unwrap_or_default ( ) ) ;
11701168 }
11711169 }
11721170 }
0 commit comments