@@ -2821,32 +2821,82 @@ fn translate_without_rowid_insert(
28212821 description : format_unique_violation_desc ( & table. name , pk_index) ,
28222822 } ) ;
28232823
2824+
28242825 program. preassign_label_to_next_insn ( ok_to_insert_label) ;
28252826 tracing:: debug!( "Uniqueness check passed. Continuing with insertion." ) ;
28262827
2828+
2829+ let physically_ordered_cols: Vec < & Column > = {
2830+ let mut ordered = Vec :: with_capacity ( table. columns . len ( ) ) ;
2831+ let mut pk_cols_added = std:: collections:: HashSet :: new ( ) ;
2832+
2833+ for pk_col_def in pk_index. columns . iter ( ) . take ( pk_index. n_key_col ) {
2834+ let ( _, col) = table. get_column ( & pk_col_def. name ) . unwrap ( ) ;
2835+ ordered. push ( col) ;
2836+ pk_cols_added. insert ( col. name . as_ref ( ) . unwrap ( ) . as_str ( ) ) ;
2837+ tracing:: trace!(
2838+ " Physical col {}: {}" ,
2839+ ordered. len( ) - 1 ,
2840+ col. name. as_ref( ) . unwrap( )
2841+ ) ;
2842+ }
2843+
2844+ for col in table. columns . iter ( ) {
2845+ if !pk_cols_added. contains ( col. name . as_ref ( ) . unwrap ( ) . as_str ( ) ) {
2846+ ordered. push ( col) ;
2847+ tracing:: trace!(
2848+ " Physical col {}: {}" ,
2849+ ordered. len( ) - 1 ,
2850+ col. name. as_ref( ) . unwrap( )
2851+ ) ;
2852+ }
2853+ }
2854+ assert_eq ! (
2855+ ordered. len( ) ,
2856+ table. columns. len( ) ,
2857+ "Physical column ordering failed: count mismatch."
2858+ ) ;
2859+ ordered
2860+ } ;
2861+
2862+ let reordered_start_reg = program. alloc_registers ( insertion. col_mappings . len ( ) ) ;
2863+ tracing:: debug!(
2864+ "Reordering columns into physical order. New registers start at {}" ,
2865+ reordered_start_reg
2866+ ) ;
2867+
2868+ for ( i, physical_col) in physically_ordered_cols. iter ( ) . enumerate ( ) {
2869+ let logical_mapping = insertion
2870+ . get_col_mapping_by_name ( physical_col. name . as_ref ( ) . unwrap ( ) )
2871+ . unwrap ( ) ;
2872+ program. emit_insn ( Insn :: Copy {
2873+ src_reg : logical_mapping. register ,
2874+ dst_reg : reordered_start_reg + i,
2875+ extra_amount : 0 ,
2876+ } ) ;
2877+ }
2878+
28272879 let full_record_reg = program. alloc_register ( ) ;
2828- let affinity_str = insertion
2829- . col_mappings
2880+ let affinity_str = physically_ordered_cols
28302881 . iter ( )
2831- . map ( |col_mapping| col_mapping . column . affinity ( ) . aff_mask ( ) )
2882+ . map ( |col| col . affinity ( ) . aff_mask ( ) )
28322883 . collect :: < String > ( ) ;
28332884
2885+
28342886 program. emit_insn ( Insn :: MakeRecord {
2835- start_reg : insertion . first_col_register ( ) ,
2887+ start_reg : reordered_start_reg ,
28362888 count : insertion. col_mappings . len ( ) ,
28372889 dest_reg : full_record_reg,
28382890 index_name : Some ( pk_index. name . clone ( ) ) ,
28392891 affinity_str : Some ( affinity_str) ,
28402892 } ) ;
2841- tracing:: debug!(
2842- "Emitted OP_MakeRecord for full row into register {}" ,
2843- full_record_reg
2844- ) ;
2893+
2894+
28452895
28462896 program. emit_insn ( Insn :: IdxInsert {
28472897 cursor_id : pk_cursor_id,
28482898 record_reg : full_record_reg,
2849- unpacked_start : Some ( insertion . first_col_register ( ) ) ,
2899+ unpacked_start : Some ( reordered_start_reg ) ,
28502900 unpacked_count : Some ( insertion. col_mappings . len ( ) as u16 ) ,
28512901 flags : IdxInsertFlags :: new ( ) . nchange ( true ) ,
28522902 } ) ;
@@ -2871,7 +2921,6 @@ fn translate_without_rowid_insert(
28712921
28722922 tracing:: debug!( "Processing secondary index '{}'" , index. name) ;
28732923
2874-
28752924 let num_key_cols = index. n_key_col ;
28762925 let key_start_reg = program. alloc_registers ( num_key_cols) ;
28772926
0 commit comments