~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbxt/src/table_xt.cc

Updated pandora-build files to version 0.133

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2005 PrimeBase Technologies GmbH
 
1
/* Copyright (c) 2005 PrimeBase Technologies GmbH
2
2
 *
3
3
 * PrimeBase XT
4
4
 *
14
14
 *
15
15
 * You should have received a copy of the GNU General Public License
16
16
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
 *
19
19
 * 2005-02-08   Paul McCullagh
20
20
 *
60
60
 
61
61
#define CHECK_TABLE_STATS
62
62
 
63
 
/* The problem is that this can take a long time
64
 
 * if the table is very large!
65
 
 */
66
 
//#define CHECK_TABLE_READ_DATA_LOG
67
 
 
68
63
#ifdef TRACE_TABLE_IDS
69
64
//#define PRINTF                xt_ftracef
70
65
#define PRINTF          xt_trace
84
79
 
85
80
/*
86
81
 * -----------------------------------------------------------------------
87
 
 * Handle Error Detected in a Table
88
 
 */
89
 
 
90
 
struct XTTableError {
91
 
        xtTableID               ter_tab_id;
92
 
        xtRecordID              ter_rec_id;
93
 
};
94
 
 
95
 
static int tab_comp_tab_error(XTThreadPtr XT_UNUSED(self), register const void *XT_UNUSED(thunk), register const void *a, register const void *b)
96
 
{
97
 
        XTTableError    *ter_a = ((XTTableError *) a);
98
 
        XTTableError    *ter_b = (XTTableError *) b;
99
 
 
100
 
        if (ter_a->ter_tab_id < ter_b->ter_tab_id)
101
 
                return -1;
102
 
        if (ter_a->ter_tab_id == ter_b->ter_tab_id) {
103
 
                if (ter_a->ter_rec_id < ter_b->ter_rec_id)
104
 
                        return -1;
105
 
                if (ter_a->ter_rec_id == ter_b->ter_rec_id)
106
 
                        return 0;
107
 
                return 1;
108
 
        }
109
 
        return 1;
110
 
}
111
 
 
112
 
static xtBool tab_record_corrupt(XTOpenTablePtr ot, xtRowID row_id, xtRecordID rec_id, bool not_valid, int where)
113
 
{
114
 
        XTTableHPtr             tab = ot->ot_table;
115
 
        XTDatabaseHPtr  db = tab->tab_db;
116
 
        XTTableError    ter;
117
 
        XTTableError    *ter_ptr;
118
 
        
119
 
        ter.ter_tab_id = tab->tab_id;
120
 
        ter.ter_rec_id = rec_id;
121
 
        
122
 
        xt_sl_lock_ns(db->db_error_list, ot->ot_thread);
123
 
        if (!(ter_ptr = (XTTableError *) xt_sl_find(NULL, db->db_error_list, &ter))) {
124
 
                xtBool  ok;
125
 
                char    table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
126
 
 
127
 
                ok = xt_sl_insert(NULL, db->db_error_list, &ter, &ter);
128
 
                xt_sl_unlock_ns(db->db_error_list);
129
 
                if (!ok)
130
 
                        return FAILED;
131
 
                xt_tab_set_table_repair_pending(tab);
132
 
                xt_tab_make_table_name(tab->tab_name, table_name, sizeof(table_name));
133
 
                xt_logf(XT_NT_ERROR, "#%d Table %s: row %llu, record %llu, is %s, REPAIR TABLE required.\n", where,
134
 
                        table_name, 
135
 
                        (u_llong) row_id,
136
 
                        (u_llong) rec_id,
137
 
                        not_valid ? "not valid" : "free");
138
 
        }
139
 
        else
140
 
                xt_sl_unlock_ns(db->db_error_list);
141
 
        return OK;
142
 
}
143
 
 
144
 
/*
145
 
 * -----------------------------------------------------------------------
146
82
 * Compare paths:
147
83
 */
148
84
 
651
587
                db->db_tables = xt_new_hashtable(self, tab_list_comp, tab_list_hash, tab_list_free, TRUE, TRUE);
652
588
        db->db_table_by_id = xt_new_sortedlist(self, sizeof(XTTableEntryRec), 20, 20, tab_comp_by_id, db, tab_free_by_id, FALSE, FALSE);
653
589
        db->db_table_paths = xt_new_sortedlist(self, sizeof(XTTablePathPtr), 20, 20, tab_comp_path, db, tab_free_path, FALSE, FALSE);
654
 
        db->db_error_list = xt_new_sortedlist(self, sizeof(XTTableError), 20, 20, tab_comp_tab_error, db, NULL, TRUE, FALSE);
655
590
 
656
591
        if (db->db_multi_path) {
657
592
                XTOpenFilePtr   of;
729
664
        }
730
665
        freer_(); // xt_describe_tables_exit(&desc)
731
666
 
732
 
        /*
733
 
         * When we open all tables, we ignore problems with foreign keys.
734
 
         * This must be done or we will not be able to load tables that
735
 
         * were created with foreign key checks off.
736
 
         */
737
 
        self->st_ignore_fkeys = 1;
738
667
        /* 
739
668
         * The purpose of this code is to ensure that all tables are opened and cached,
740
669
         * which is actually only required if tables have foreign key references.
766
695
                else
767
696
                        xt_log_and_clear_warning(self);
768
697
        }
769
 
        self->st_ignore_fkeys = 0;
770
698
 
771
699
        popr_(); // Discard xt_tab_exit_db(db)
772
700
        exit_();
943
871
                xt_free_sortedlist(self, db->db_table_paths);
944
872
                db->db_table_paths = NULL;
945
873
        }
946
 
        if (db->db_error_list) {
947
 
                xt_free_sortedlist(self, db->db_error_list);
948
 
                db->db_error_list = NULL;
949
 
        }
950
874
}
951
875
 
952
876
 
1530
1454
        if (tab->tab_dic.dic_table) {
1531
1455
                try_(a) {
1532
1456
                        tab->tab_dic.dic_table->attachReferences(self, db);
1533
 
                }
1534
 
                catch_(a) {
1535
 
                        /* Errors are thrown when: set foreign_key_checks = 1 */
1536
 
                        /* Undo everything done above: */
1537
 
                        xt_ht_del(self, db->db_tables, tab->tab_name);
1538
 
                        xt_throw(self);
1539
 
                }
1540
 
                cont_(a);
 
1457
                } catch_(a) {
 
1458
                        /* ignore problems of referenced tables */
 
1459
                        xt_log_and_clear_warning(self);
 
1460
                } cont_(a);
1541
1461
        }
1542
1462
 
1543
1463
        *r_tab = tab;
2092
2012
        exit_();
2093
2013
}
2094
2014
 
2095
 
xtPublic void xt_tab_check_free_lists(XTThreadPtr self, XTOpenTablePtr ot, bool check_recs, bool correct_count)
2096
 
{
2097
 
        char                                    table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
2098
 
        register XTTableHPtr    tab = ot->ot_table;
2099
 
        xtRowID                                 prev_row_id;
2100
 
        xtRowID                                 row_id;
2101
 
        xtRefID                                 next_row_id;
2102
 
        u_llong                                 free_count;
2103
 
 
2104
 
        xt_tab_make_table_name(tab->tab_name, table_name, sizeof(table_name));
2105
 
        if (check_recs) {
2106
 
                xtRecordID              prev_rec_id;
2107
 
                xtRecordID              rec_id;
2108
 
                XTTabRecExtDRec rec_buf;
2109
 
 
2110
 
                xt_lock_mutex_ns(&tab->tab_rec_lock);
2111
 
                /* Checking the free list: */
2112
 
                prev_rec_id = 0;
2113
 
                free_count = 0;
2114
 
                rec_id = tab->tab_rec_free_id;
2115
 
                while (rec_id) {
2116
 
                        if (rec_id >= tab->tab_rec_eof_id) {
2117
 
                                xt_logf(XT_NT_ERROR, "Table %s: invalid reference on free list: %llu, ", table_name, (u_llong) rec_id);
2118
 
                                if (prev_rec_id)
2119
 
                                        xt_logf(XT_NT_ERROR, "reference by: %llu\n", (u_llong) prev_rec_id);
2120
 
                                else
2121
 
                                        xt_logf(XT_NT_ERROR, "reference by list head pointer\n");
2122
 
                                xt_tab_set_table_repair_pending(tab);
2123
 
                                break;
2124
 
                        }
2125
 
                        if (!xt_tab_get_rec_data(ot, rec_id, XT_REC_FIX_HEADER_SIZE, (xtWord1 *) &rec_buf)) {
2126
 
                                if (self)
2127
 
                                        xt_throw(self);
2128
 
                                else
2129
 
                                        xt_log_and_clear_warning(ot->ot_thread);
2130
 
                                break;
2131
 
                        }
2132
 
                        if ((rec_buf.tr_rec_type_1 & XT_TAB_STATUS_MASK) != XT_TAB_STATUS_FREED)
2133
 
                                xt_logf(XT_NT_INFO, "Table %s: record, %llu, on free list is not free\n", table_name, (u_llong) rec_id);
2134
 
                        free_count++;
2135
 
                        prev_rec_id = rec_id;
2136
 
                        rec_id = XT_GET_DISK_4(rec_buf.tr_prev_rec_id_4);
2137
 
                }
2138
 
                if (free_count != tab->tab_rec_fnum) {
2139
 
                        if (correct_count) {
2140
 
                                tab->tab_rec_fnum = free_count;
2141
 
                                tab->tab_head_rec_fnum = free_count;
2142
 
                                tab->tab_flush_pending = TRUE;
2143
 
                                xt_logf(XT_NT_INFO, "Table %s: free record count (%llu) has been set to the number of records on the list: %llu\n", table_name, (u_llong) tab->tab_rec_fnum, (u_llong) free_count);
2144
 
                        }
2145
 
                        else
2146
 
                                xt_logf(XT_NT_INFO, "Table %s: free record count (%llu) differs from the number of records on the list: %llu\n", table_name, (u_llong) tab->tab_rec_fnum, (u_llong) free_count);
2147
 
                }
2148
 
                xt_unlock_mutex_ns(&tab->tab_rec_lock);
2149
 
        }
2150
 
 
2151
 
        /* Check the row free list: */
2152
 
        xt_lock_mutex_ns(&tab->tab_row_lock);
2153
 
 
2154
 
        prev_row_id = 0;
2155
 
        free_count = 0;
2156
 
        row_id = tab->tab_row_free_id;
2157
 
        while (row_id) {
2158
 
                if (row_id >= tab->tab_row_eof_id) {
2159
 
                        xt_logf(XT_NT_ERROR, "Table %s: invalid reference on free row: %llu, ", table_name, (u_llong) row_id);
2160
 
                        if (prev_row_id)
2161
 
                                xt_logf(XT_NT_ERROR, "reference by: %llu\n", (u_llong) prev_row_id);
2162
 
                        else
2163
 
                                xt_logf(XT_NT_ERROR, "reference by list head pointer\n");
2164
 
                        xt_tab_set_table_repair_pending(tab);
2165
 
                        break;
2166
 
                }
2167
 
                if (!tab->tab_rows.xt_tc_read_4(ot->ot_row_file, row_id, &next_row_id, ot->ot_thread)) {
2168
 
                        if (self)
2169
 
                                xt_throw(self);
2170
 
                        else
2171
 
                                xt_log_and_clear_warning(ot->ot_thread);
2172
 
                        break;
2173
 
                }
2174
 
                free_count++;
2175
 
                prev_row_id = row_id;
2176
 
                row_id = next_row_id;
2177
 
        }
2178
 
        if (free_count != tab->tab_row_fnum) {
2179
 
                if (correct_count) {
2180
 
                        /* tab_row_fnum is the current value, and tab_head_row_fnum is the value on
2181
 
                         * disk. tab_head_row_fnum is set by the writer as the changes are applied
2182
 
                         * to the database.
2183
 
                         *
2184
 
                         * This is the value then stored in the header of the file. This value
2185
 
                         * is in sync with other changes to the file.
2186
 
                         *
2187
 
                         * So the fact that I am setting both value means this will not work at
2188
 
                         * runtime, unless all changes have been applied by the writer.
2189
 
                         *
2190
 
                         * The correct way to do this at run time would be to add the change to the
2191
 
                         * transaction log, so that it is applied by the writer.
2192
 
                         */
2193
 
                        tab->tab_row_fnum = free_count;
2194
 
                        tab->tab_head_row_fnum = free_count;
2195
 
                        tab->tab_flush_pending = TRUE;
2196
 
                        xt_logf(XT_NT_INFO, "Table %s: free row count (%llu) has been set to the number of rows on the list: %llu\n", table_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count);
2197
 
                }
2198
 
                else
2199
 
                        xt_logf(XT_NT_INFO, "Table %s: free row count (%llu) differs from the number of rows on the list: %llu\n", table_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count);
2200
 
        }
2201
 
 
2202
 
        xt_unlock_mutex_ns(&tab->tab_row_lock);
2203
 
}
2204
 
 
2205
2015
/*
2206
2016
 * Record buffer size:
2207
2017
 * -------------------
2282
2092
        XTTableHPtr                             tab = ot->ot_table;
2283
2093
        xtRecordID                              prec_id;
2284
2094
        XTTabRecExtDPtr                 rec_buf = (XTTabRecExtDPtr) ot->ot_row_rbuffer;
2285
 
#ifdef CHECK_TABLE_READ_DATA_LOG
2286
2095
        XTactExtRecEntryDRec    ext_rec;
2287
2096
        size_t                                  log_size;
2288
2097
        xtLogID                                 log_id;
2289
2098
        xtLogOffset                             log_offset;
2290
 
#endif
2291
2099
        xtRecordID                              rec_id;
2292
2100
        xtRecordID                              prev_rec_id;
2293
2101
        xtXactID                                xn_id;
2301
2109
        size_t                                  rec_size;
2302
2110
        size_t                                  row_size;
2303
2111
        u_llong                                 ext_data_len = 0;
2304
 
        u_llong                                 ext_rec_count = 0;
2305
2112
 
2306
2113
#if defined(DUMP_CHECK_TABLE) || defined(CHECK_TABLE_STATS)
2307
2114
        printf("\nCHECK TABLE: %s\n", tab->tab_name->ps_path);
2405
2212
                                printf("record-X ");
2406
2213
#endif
2407
2214
                                alloc_rec_count++;
2408
 
                                ext_rec_count++;
2409
2215
                                ext_data_len += XT_GET_DISK_4(rec_buf->re_log_dat_siz_4);
2410
2216
                                row_size = XT_GET_DISK_4(rec_buf->re_log_dat_siz_4) + ot->ot_rec_size - XT_REC_EXT_HEADER_SIZE;
2411
2217
                                alloc_rec_bytes += row_size;
2431
2237
#endif
2432
2238
                                break;
2433
2239
                        case XT_TAB_STATUS_EXT_DLOG:
 
2240
                                xtBool ok;
 
2241
 
2434
2242
#ifdef DUMP_CHECK_TABLE
2435
2243
                                printf(" prev=%-3llu  xact=%-3llu row=%lu  Xlog=%lu Xoff=%llu Xsiz=%lu\n", (u_llong) prev_rec_id, (u_llong) xn_id, (u_long) row_id, (u_long) XT_GET_DISK_2(rec_buf->re_log_id_2), (u_llong) XT_GET_DISK_6(rec_buf->re_log_offs_6), (u_long) XT_GET_DISK_4(rec_buf->re_log_dat_siz_4));
2436
2244
#endif
2437
2245
 
2438
 
#ifdef CHECK_TABLE_READ_DATA_LOG
2439
 
                                xtBool ok;
2440
 
 
2441
2246
                                log_size = XT_GET_DISK_4(rec_buf->re_log_dat_siz_4);
2442
2247
                                XT_GET_LOG_REF(log_id, log_offset, rec_buf);
2443
2248
                                if (ot->ot_table->tab_dic.dic_tab_flags & XT_TF_MEMORY_TABLE) {
2460
2265
                                                xt_logf(XT_INFO, "Table %s: record %llu, extended record %lu:%llu not valid\n", tab->tab_name, (u_llong) rec_id, (u_long) log_id, (u_llong) log_offset);
2461
2266
                                        }
2462
2267
                                }
2463
 
#endif
2464
2268
                                break;
2465
2269
                        default:
2466
2270
#ifdef DUMP_CHECK_TABLE
2482
2286
                if (!tab->tab_dic.dic_rec_fixed) {
2483
2287
                        xt_int8_to_byte_size((xtInt8) tab->tab_mem_total, value);
2484
2288
                        printf("Ext. record memory used = %s\n", value);
2485
 
                        printf("Extended record count   = %llu\n", ext_rec_count);
2486
2289
                }
2487
2290
                xt_int8_to_byte_size((xtInt8) ind, value);
2488
2291
                printf("Index data memory used  = %s\n", value);
2495
2298
                if (!tab->tab_dic.dic_rec_fixed) {
2496
2299
                        xt_int8_to_byte_size((xtInt8) ext_data_len, value);
2497
2300
                        printf("Ext. record disk used   = %s\n", value);                
2498
 
                        printf("Extended record count   = %llu\n", ext_rec_count);
2499
2301
                }
2500
2302
                xt_int8_to_byte_size((xtInt8) ind, value);
2501
2303
                printf("Index disk space used   = %s\n", value);
2540
2342
                prec_id = rec_id;
2541
2343
                rec_id = XT_GET_DISK_4(rec_buf->tr_prev_rec_id_4);
2542
2344
        }
2543
 
        if (free_count2 != free_rec_count)
 
2345
        if (free_count2 < free_rec_count)
2544
2346
                xt_logf(XT_INFO, "Table %s: not all free blocks (%llu) on free list: %llu\n", tab->tab_name, (u_llong) free_rec_count, (u_llong) free_count2);
2545
2347
 
2546
2348
        freer_(); // xt_unlock_mutex_ns(&tab->tab_rec_lock);
2572
2374
                rec_id++;
2573
2375
        }
2574
2376
 
2575
 
        prec_id = 0;
2576
 
        free_count2 = 0;
2577
 
        row_id = tab->tab_row_free_id;
2578
 
        while (row_id) {
2579
 
                if (row_id >= tab->tab_row_eof_id) {
2580
 
                        xt_logf(XT_INFO, "Table %s: invalid reference on free row: %llu, ", tab->tab_name, (u_llong) row_id);
2581
 
                        if (prec_id)
2582
 
                                xt_logf(XT_INFO, "reference by: %llu\n", (u_llong) prec_id);
2583
 
                        else
2584
 
                                xt_logf(XT_INFO, "reference by list head pointer\n");
2585
 
                        break;
2586
 
                }
2587
 
                if (!tab->tab_rows.xt_tc_read_4(ot->ot_row_file, row_id, &ref_id, self)) {
2588
 
                        xt_log_and_clear_exception(self);
2589
 
                        break;
2590
 
                }
2591
 
                free_count2++;
2592
 
                prec_id = row_id;
2593
 
                row_id = ref_id;
2594
 
        }
2595
 
        if (free_count2 != tab->tab_row_fnum)
2596
 
                xt_logf(XT_INFO, "Table %s: free row count (%llu) differs from the number of row on the list: %llu\n", tab->tab_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count2);
2597
 
 
2598
2377
        freer_(); // xt_unlock_mutex(&tab->tab_row_lock);
2599
2378
 
2600
2379
#ifdef CHECK_INDEX_ON_CHECK_TABLE
3811
3590
#endif
3812
3591
                                break;
3813
3592
                        case XT_XN_REREAD:
3814
 
                                /* {RETRY-READ}
3815
 
                                 * TODO: This is not as "correct" as it could be.
3816
 
                                 * Such records should be considered to be aborted,
3817
 
                                 * and removed from the list.
3818
 
                                 */
3819
3593
                                if (invalid_rec != var_rec_id) {
3820
3594
                                        invalid_rec = var_rec_id;
3821
3595
                                        goto retry_3;
3822
3596
                                }
3823
 
                                if (!tab_record_corrupt(ot, row_id, var_rec_id, true, 1))
3824
 
                                        goto failed;
3825
 
 
3826
3597
                                /* Assume end of list. */
3827
3598
#ifdef XT_CRASH_DEBUG
3828
3599
                                /* Should not happen! */
4010
3781
                        /* Avoid infinite loop: */
4011
3782
                        if (read_again) {
4012
3783
                                /* Should not happen! */
4013
 
                                if (!tab_record_corrupt(ot, row_id, ot->ot_curr_rec_id, true, 2))
4014
 
                                        return XT_ERR;
4015
3784
#ifdef XT_CRASH_DEBUG
4016
3785
                                /* Generate a core dump! */
4017
3786
                                xt_crash_me();
4068
3837
                        /* Avoid infinite loop: */
4069
3838
                        if (read_again) {
4070
3839
                                /* Should not happen! */
4071
 
                                if (!tab_record_corrupt(ot, XT_GET_DISK_4(((XTTabRecHeadDPtr) ot->ot_row_rbuffer)->tr_row_id_4), ot->ot_curr_rec_id, true, 3))
4072
 
                                        return XT_ERR;
4073
3840
#ifdef XT_CRASH_DEBUG
4074
3841
                                /* Generate a core dump! */
4075
3842
                                xt_crash_me();
4286
4053
        }
4287
4054
        tab->tab_row_free_id = row_id;
4288
4055
        tab->tab_row_fnum++;
4289
 
        ASSERT_NS(tab->tab_row_fnum < tab->tab_row_eof_id);
4290
4056
        xt_unlock_mutex_ns(&tab->tab_row_lock);
4291
4057
 
4292
4058
        if (!xt_xlog_modify_table(tab->tab_id, XT_LOG_ENT_ROW_FREED, op_seq, 0, 0, row_id, sizeof(XTTabRowRefDRec), (xtWord1 *) &free_row, ot->ot_thread))
4487
4253
                xt_lock_mutex_ns(&tab->tab_db->db_co_ext_lock);
4488
4254
                if (!xt_tab_get_rec_data(ot, rec_id, XT_REC_EXT_HEADER_SIZE, ot->ot_row_rbuffer)) {
4489
4255
                        xt_unlock_mutex_ns(&tab->tab_db->db_co_ext_lock);
4490
 
                        return XT_ERR;
 
4256
                        return FAILED;
4491
4257
                }
4492
4258
                xt_unlock_mutex_ns(&tab->tab_db->db_co_ext_lock);
4493
4259
 
4573
4339
        XT_SET_DISK_4(free_rec->rf_next_rec_id_4, prev_rec_id);
4574
4340
        if (!xt_tab_put_rec_data(ot, rec_id, sizeof(XTTabRecFreeDRec), ot->ot_row_rbuffer, &op_seq)) {
4575
4341
                xt_unlock_mutex_ns(&tab->tab_rec_lock);
4576
 
                return XT_ERR;
 
4342
                return FAILED;
4577
4343
        }
4578
4344
        tab->tab_rec_free_id = rec_id;
4579
4345
        ASSERT_NS(tab->tab_rec_free_id < tab->tab_rec_eof_id);
4582
4348
        xt_unlock_mutex_ns(&tab->tab_rec_lock);
4583
4349
 
4584
4350
        free_rec->rf_rec_type_1 = old_rec_type;
4585
 
        if (!xt_xlog_modify_table(tab->tab_id, status, op_seq, new_rec_type, prev_rec_id, rec_id, rec_size, ot->ot_row_rbuffer, ot->ot_thread))
4586
 
                return XT_ERR;
4587
 
        return OK;
 
4351
        return xt_xlog_modify_table(tab->tab_id, status, op_seq, new_rec_type, prev_rec_id, rec_id, rec_size, ot->ot_row_rbuffer, ot->ot_thread);
4588
4352
}
4589
4353
 
4590
4354
static xtRowID tab_new_row(XTOpenTablePtr ot, XTTableHPtr tab)
4603
4367
                        return 0;
4604
4368
                }
4605
4369
                tab->tab_row_free_id = next_row_id;
4606
 
                ASSERT_NS(tab->tab_row_fnum > 0);
4607
4370
                tab->tab_row_fnum--;
4608
4371
        }
4609
4372
        else {
4909
4672
                        return FAILED;
4910
4673
                if (XT_REC_IS_CLEAN(var_head.tr_rec_type_1))
4911
4674
                        goto locked;
4912
 
                if (XT_REC_IS_FREE(var_head.tr_rec_type_1)) {
 
4675
                if (XT_REC_IS_FREE(var_head.tr_rec_type_1))
4913
4676
                        /* Should not happen: */
4914
 
                        if (!tab_record_corrupt(ot, row_id, var_rec_id, false, 4))
4915
 
                                return FAILED;
4916
4677
                        goto record_invalid;
4917
 
                }
4918
4678
                xn_id = XT_GET_DISK_4(var_head.tr_xact_id_4);
4919
4679
                switch (xt_xn_status(ot, xn_id, var_rec_id)) {
4920
4680
                        case XT_XN_VISIBLE:
4937
4697
                                XT_TAB_ROW_WRITE_LOCK(&tab->tab_row_rwlock[row_id % XT_ROW_RWLOCKS], ot->ot_thread);
4938
4698
                                goto retry;
4939
4699
                        case XT_XN_REREAD:
4940
 
                                if (!tab_record_corrupt(ot, row_id, var_rec_id, true, 5))
4941
 
                                        return FAILED;
4942
4700
                                goto record_invalid;
4943
4701
                }
4944
4702
                var_rec_id = XT_GET_DISK_4(var_head.tr_prev_rec_id_4);
4950
4708
        return FAILED;
4951
4709
        
4952
4710
        record_invalid:
4953
 
        /* {RETRY-READ} */
4954
4711
        /* Prevent an infinite loop due to a bad record: */
4955
4712
        if (invalid_rec != var_rec_id) {
4956
 
                invalid_rec = var_rec_id;
 
4713
                var_rec_id = invalid_rec;
4957
4714
                goto retry;
4958
4715
        }
4959
4716
        /* The record is invalid, it will be "overwritten"... */
4976
4733
        xtXactID                                rec_xn_id = 0;
4977
4734
        xtBool                                  wait = FALSE;
4978
4735
        xtXactID                                wait_xn_id = 0;
4979
 
        xtRowID                                 row_id = 0;  // Initialized unnecessarily to satisfy (Drizzle) compile [-Wuninitialized]
 
4736
        xtRowID                                 row_id;
4980
4737
        xtRecordID                              var_rec_id;
4981
4738
        xtXactID                                xn_id;
4982
 
        register XTTableHPtr    tab = NULL; // Initialized unnecessarily to satisfy (Drizzle) compile [-Wuninitialized]
 
4739
        register XTTableHPtr    tab;
4983
4740
#ifdef TRACE_VARIATIONS_IN_DUP_CHECK
4984
4741
        char                                    t_buf[500];
4985
4742
        int                                             len;
5025
4782
#ifdef TRACE_VARIATIONS_IN_DUP_CHECK
5026
4783
                                t_type="Re-read";
5027
4784
#endif
5028
 
                                /* {RETRY-READ} */
5029
4785
                                /* Avoid infinite loop: */
5030
4786
                                if (invalid_rec == rec_id) {
5031
4787
                                        /* Should not happen! */
5032
 
                                        if (!tab_record_corrupt(ot, XT_GET_DISK_4(rec_head.tr_row_id_4), rec_id, true, 6))
5033
 
                                                goto failed;
5034
4788
#ifdef XT_CRASH_DEBUG
5035
4789
                                        /* Generate a core dump! */
5036
4790
                                        xt_crash_me();
5075
4829
                if (XT_REC_IS_FREE(rec_head.tr_rec_type_1)) {
5076
4830
                        /* Should not happen: */
5077
4831
                        if (invalid_rec != var_rec_id) {
5078
 
                                invalid_rec = var_rec_id;
 
4832
                                var_rec_id = invalid_rec;
5079
4833
                                goto retry;
5080
4834
                        }
5081
4835
                        /* Assume end of list. */
5112
4866
                                }
5113
4867
                                break;
5114
4868
                        case XT_XN_REREAD:
5115
 
                                /* {RETRY-READ} */
5116
4869
                                if (invalid_rec != var_rec_id) {
5117
 
                                        invalid_rec = var_rec_id;
 
4870
                                        var_rec_id = invalid_rec;
5118
4871
                                        goto retry;
5119
4872
                                }
5120
4873
                                /* Assume end of list. */
5121
 
                                if (!tab_record_corrupt(ot, row_id, invalid_rec, true, 7))
5122
 
                                        goto failed;
5123
4874
#ifdef XT_CRASH_DEBUG
5124
4875
                                /* Should not happen! */
5125
4876
                                xt_crash_me();
5855
5606
                                ot->ot_on_page = FALSE;
5856
5607
                                goto next_page;
5857
5608
                        }
5858
 
                        if (!tab_record_corrupt(ot, XT_GET_DISK_4(((XTTabRecHeadDPtr) buff_ptr)->tr_row_id_4), invalid_rec, true, 8))
5859
 
                                return XT_ERR;
5860
5609
#ifdef XT_CRASH_DEBUG
5861
5610
                        /* Should not happen! */
5862
5611
                        xt_crash_me();