@@ -2841,32 +2841,82 @@ fn translate_without_rowid_insert(
28412841 description : format_unique_violation_desc ( & table. name , pk_index) ,
28422842 } ) ;
28432843
2844+
28442845 program. preassign_label_to_next_insn ( ok_to_insert_label) ;
28452846 tracing:: debug!( "Uniqueness check passed. Continuing with insertion." ) ;
28462847
2848+
2849+ let physically_ordered_cols: Vec < & Column > = {
2850+ let mut ordered = Vec :: with_capacity ( table. columns . len ( ) ) ;
2851+ let mut pk_cols_added = std:: collections:: HashSet :: new ( ) ;
2852+
2853+ for pk_col_def in pk_index. columns . iter ( ) . take ( pk_index. n_key_col ) {
2854+ let ( _, col) = table. get_column ( & pk_col_def. name ) . unwrap ( ) ;
2855+ ordered. push ( col) ;
2856+ pk_cols_added. insert ( col. name . as_ref ( ) . unwrap ( ) . as_str ( ) ) ;
2857+ tracing:: trace!(
2858+ " Physical col {}: {}" ,
2859+ ordered. len( ) - 1 ,
2860+ col. name. as_ref( ) . unwrap( )
2861+ ) ;
2862+ }
2863+
2864+ for col in table. columns . iter ( ) {
2865+ if !pk_cols_added. contains ( col. name . as_ref ( ) . unwrap ( ) . as_str ( ) ) {
2866+ ordered. push ( col) ;
2867+ tracing:: trace!(
2868+ " Physical col {}: {}" ,
2869+ ordered. len( ) - 1 ,
2870+ col. name. as_ref( ) . unwrap( )
2871+ ) ;
2872+ }
2873+ }
2874+ assert_eq ! (
2875+ ordered. len( ) ,
2876+ table. columns. len( ) ,
2877+ "Physical column ordering failed: count mismatch."
2878+ ) ;
2879+ ordered
2880+ } ;
2881+
2882+ let reordered_start_reg = program. alloc_registers ( insertion. col_mappings . len ( ) ) ;
2883+ tracing:: debug!(
2884+ "Reordering columns into physical order. New registers start at {}" ,
2885+ reordered_start_reg
2886+ ) ;
2887+
2888+ for ( i, physical_col) in physically_ordered_cols. iter ( ) . enumerate ( ) {
2889+ let logical_mapping = insertion
2890+ . get_col_mapping_by_name ( physical_col. name . as_ref ( ) . unwrap ( ) )
2891+ . unwrap ( ) ;
2892+ program. emit_insn ( Insn :: Copy {
2893+ src_reg : logical_mapping. register ,
2894+ dst_reg : reordered_start_reg + i,
2895+ extra_amount : 0 ,
2896+ } ) ;
2897+ }
2898+
28472899 let full_record_reg = program. alloc_register ( ) ;
2848- let affinity_str = insertion
2849- . col_mappings
2900+ let affinity_str = physically_ordered_cols
28502901 . iter ( )
2851- . map ( |col_mapping| col_mapping . column . affinity ( ) . aff_mask ( ) )
2902+ . map ( |col| col . affinity ( ) . aff_mask ( ) )
28522903 . collect :: < String > ( ) ;
28532904
2905+
28542906 program. emit_insn ( Insn :: MakeRecord {
2855- start_reg : insertion . first_col_register ( ) ,
2907+ start_reg : reordered_start_reg ,
28562908 count : insertion. col_mappings . len ( ) ,
28572909 dest_reg : full_record_reg,
28582910 index_name : Some ( pk_index. name . clone ( ) ) ,
28592911 affinity_str : Some ( affinity_str) ,
28602912 } ) ;
2861- tracing:: debug!(
2862- "Emitted OP_MakeRecord for full row into register {}" ,
2863- full_record_reg
2864- ) ;
2913+
2914+
28652915
28662916 program. emit_insn ( Insn :: IdxInsert {
28672917 cursor_id : pk_cursor_id,
28682918 record_reg : full_record_reg,
2869- unpacked_start : Some ( insertion . first_col_register ( ) ) ,
2919+ unpacked_start : Some ( reordered_start_reg ) ,
28702920 unpacked_count : Some ( insertion. col_mappings . len ( ) as u16 ) ,
28712921 flags : IdxInsertFlags :: new ( ) . nchange ( true ) ,
28722922 } ) ;
@@ -2891,7 +2941,6 @@ fn translate_without_rowid_insert(
28912941
28922942 tracing:: debug!( "Processing secondary index '{}'" , index. name) ;
28932943
2894-
28952944 let num_key_cols = index. n_key_col ;
28962945 let key_start_reg = program. alloc_registers ( num_key_cols) ;
28972946
0 commit comments