@@ -515,12 +515,15 @@ constexpr size_t inst_col_info_size = 6;
515
515
@param[in] is_comp true if COMP
516
516
@param[in] is_versioned if table has row versions
517
517
@param[in] is_instant true if table has INSTANT cols
518
+ @param[in] fields_with_changed_order bitmap to indicate fields with changed
519
+ order
518
520
@param[out] size_needed total size needed on REDO LOG */
519
521
static void log_index_get_size_needed (const dict_index_t *index, size_t size,
520
522
uint16_t n, bool is_comp,
521
523
bool is_versioned, bool is_instant,
524
+ const bool *fields_with_changed_order,
522
525
size_t &size_needed) {
523
- auto size_for_versioned_fields = [](const dict_index_t *ind) {
526
+ auto size_for_versioned_fields = [& ](const dict_index_t *ind) {
524
527
size_t _size = 0 ;
525
528
/* 2 bytes for number of columns with version */
526
529
_size += 2 ;
@@ -530,6 +533,16 @@ static void log_index_get_size_needed(const dict_index_t *index, size_t size,
530
533
ut_ad (n_versioned_fields != 0 );
531
534
532
535
_size += n_versioned_fields * inst_col_info_size;
536
+
537
+ /* For fields with changed order */
538
+ size_t n_changed_order_fields = 0 ;
539
+ for (size_t i = 0 ; i < n; i++) {
540
+ if (fields_with_changed_order[i]) {
541
+ n_changed_order_fields++;
542
+ }
543
+ }
544
+ _size += n_changed_order_fields * inst_col_info_size;
545
+
533
546
return (_size);
534
547
};
535
548
@@ -799,9 +812,33 @@ bool mlog_open_and_write_index(mtr_t *mtr, const byte *rec,
799
812
n = DICT_INDEX_SPATIAL_NODEPTR_SIZE;
800
813
}
801
814
815
+ /* Ordinal position of an existing field can't be changed with INSTANT
816
+ algorithm. But when it is combined with ADD/DROP COLUMN, ordinal position
817
+ of a filed can be changed. This bool array of size #fields in index,
818
+ represents if ordinal position of an existing filed is changed. */
819
+ bool *fields_with_changed_order = nullptr ;
820
+ if (is_versioned) {
821
+ fields_with_changed_order = new bool [n];
822
+ memset (fields_with_changed_order, false , (sizeof (bool ) * n));
823
+
824
+ uint16_t phy_pos = 0 ;
825
+ for (size_t i = 0 ; i < n; i++) {
826
+ dict_field_t *field = index->get_field (i);
827
+ const dict_col_t *col = field->col ;
828
+
829
+ if (col->is_instant_added () || col->is_instant_dropped ()) {
830
+ continue ;
831
+ } else if (field->get_phy_pos () >= phy_pos) {
832
+ phy_pos = field->get_phy_pos ();
833
+ } else {
834
+ fields_with_changed_order[i] = true ;
835
+ }
836
+ }
837
+ }
838
+
802
839
size_t size_needed = 0 ;
803
840
log_index_get_size_needed (index, size, n, is_comp, is_versioned, is_instant,
804
- size_needed);
841
+ fields_with_changed_order, size_needed);
805
842
size_t total = size_needed;
806
843
size_t alloc = total;
807
844
if (alloc > mtr_buf_t ::MAX_DATA_SIZE) {
@@ -846,30 +883,6 @@ bool mlog_open_and_write_index(mtr_t *mtr, const byte *rec,
846
883
return true ;
847
884
};
848
885
849
- /* Ordinal position of an existing field can't be changed with INSTANT
850
- algorithm. But when it is combined with ADD/DROP COLUMN, ordinal position
851
- of a filed can be changed. This bool array of size #fields in index,
852
- represents if ordinal position of an existing filed is changed. */
853
- bool *fields_with_changed_order = nullptr ;
854
- if (is_versioned) {
855
- fields_with_changed_order = new bool [n];
856
- memset (fields_with_changed_order, false , (sizeof (bool ) * n));
857
-
858
- uint16_t phy_pos = 0 ;
859
- for (size_t i = 0 ; i < n; i++) {
860
- dict_field_t *field = index->get_field (i);
861
- const dict_col_t *col = field->col ;
862
-
863
- if (col->is_instant_added () || col->is_instant_dropped ()) {
864
- continue ;
865
- } else if (field->get_phy_pos () >= phy_pos) {
866
- phy_pos = field->get_phy_pos ();
867
- } else {
868
- fields_with_changed_order[i] = true ;
869
- }
870
- }
871
- }
872
-
873
886
if (is_comp) {
874
887
/* Write fields info. */
875
888
if (!log_index_fields (index, n, is_versioned, instant_fields_to_log,
0 commit comments