~ubuntu-branches/ubuntu/quantal/mysql-5.5/quantal-security

« back to all changes in this revision

Viewing changes to storage/innobase/rem/rem0rec.c

  • Committer: Package Import Robot
  • Author(s): Seth Arnold
  • Date: 2013-04-18 18:15:39 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20130418181539-7uo1w041b4h2ulbs
Tags: 5.5.31-0ubuntu0.12.10.1
* SECURITY UPDATE: Update to 5.5.31 to fix security issues (LP: #1170516)
  - http://www.oracle.com/technetwork/topics/security/cpuapr2013-1899555.html
* debian/patches/71_disable_rpl_tests.patch: refreshed.
* debian/patches/fix-mysqldump-test.patch: removed, fixed differently
  upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
167
167
{
168
168
        const byte*     nulls;
169
169
        const byte*     lens;
170
 
        dict_field_t*   field;
171
170
        ulint           null_mask;
172
171
        ulint           n_extern;
173
172
        ulint           i;
188
187
 
189
188
        /* read the lengths of fields 0..n */
190
189
        do {
191
 
                ulint   len;
 
190
                const dict_field_t*     field
 
191
                        = dict_index_get_nth_field(index, i);
 
192
                const dict_col_t*       col
 
193
                        = dict_field_get_col(field);
 
194
                ulint                   len;
192
195
 
193
 
                field = dict_index_get_nth_field(index, i);
194
 
                if (!(dict_field_get_col(field)->prtype & DATA_NOT_NULL)) {
 
196
                if (!(col->prtype & DATA_NOT_NULL)) {
195
197
                        /* nullable field => read the null flag */
196
198
 
197
199
                        if (UNIV_UNLIKELY(!(byte) null_mask)) {
209
211
 
210
212
                if (UNIV_UNLIKELY(!field->fixed_len)) {
211
213
                        /* Variable-length field: read the length */
212
 
                        const dict_col_t*       col
213
 
                                = dict_field_get_col(field);
214
214
                        len = *lens--;
215
215
                        /* If the maximum length of the field is up
216
216
                        to 255 bytes, the actual length is always
239
239
Determine the offset to each field in a leaf-page record
240
240
in ROW_FORMAT=COMPACT.  This is a special case of
241
241
rec_init_offsets() and rec_get_offsets_func(). */
242
 
UNIV_INTERN
 
242
UNIV_INLINE __attribute__((nonnull))
243
243
void
244
244
rec_init_offsets_comp_ordinary(
245
245
/*===========================*/
246
246
        const rec_t*            rec,    /*!< in: physical record in
247
247
                                        ROW_FORMAT=COMPACT */
248
 
        ulint                   extra,  /*!< in: number of bytes to reserve
249
 
                                        between the record header and
250
 
                                        the data payload
251
 
                                        (usually REC_N_NEW_EXTRA_BYTES) */
 
248
        ibool                   temp,   /*!< in: whether to use the
 
249
                                        format for temporary files in
 
250
                                        index creation */
252
251
        const dict_index_t*     index,  /*!< in: record descriptor */
253
252
        ulint*                  offsets)/*!< in/out: array of offsets;
254
253
                                        in: n=rec_offs_n_fields(offsets) */
256
255
        ulint           i               = 0;
257
256
        ulint           offs            = 0;
258
257
        ulint           any_ext         = 0;
259
 
        const byte*     nulls           = rec - (extra + 1);
 
258
        const byte*     nulls           = temp
 
259
                ? rec - 1
 
260
                : rec - (1 + REC_N_NEW_EXTRA_BYTES);
260
261
        const byte*     lens            = nulls
261
262
                - UT_BITS_IN_BYTES(index->n_nullable);
262
 
        dict_field_t*   field;
263
263
        ulint           null_mask       = 1;
264
264
 
265
265
#ifdef UNIV_DEBUG
266
 
        /* We cannot invoke rec_offs_make_valid() here, because it can hold
267
 
        that extra != REC_N_NEW_EXTRA_BYTES.  Similarly, rec_offs_validate()
268
 
        will fail in that case, because it invokes rec_get_status(). */
 
266
        /* We cannot invoke rec_offs_make_valid() here if temp=TRUE.
 
267
        Similarly, rec_offs_validate() will fail in that case, because
 
268
        it invokes rec_get_status(). */
269
269
        offsets[2] = (ulint) rec;
270
270
        offsets[3] = (ulint) index;
271
271
#endif /* UNIV_DEBUG */
272
272
 
 
273
        ut_ad(temp || dict_table_is_comp(index->table));
 
274
 
 
275
        if (temp && dict_table_is_comp(index->table)) {
 
276
                /* No need to do adjust fixed_len=0. We only need to
 
277
                adjust it for ROW_FORMAT=REDUNDANT. */
 
278
                temp = FALSE;
 
279
        }
 
280
 
273
281
        /* read the lengths of fields 0..n */
274
282
        do {
275
 
                ulint   len;
 
283
                const dict_field_t*     field
 
284
                        = dict_index_get_nth_field(index, i);
 
285
                const dict_col_t*       col
 
286
                        = dict_field_get_col(field);
 
287
                ulint                   len;
276
288
 
277
 
                field = dict_index_get_nth_field(index, i);
278
 
                if (!(dict_field_get_col(field)->prtype
279
 
                      & DATA_NOT_NULL)) {
 
289
                if (!(col->prtype & DATA_NOT_NULL)) {
280
290
                        /* nullable field => read the null flag */
281
291
 
282
292
                        if (UNIV_UNLIKELY(!(byte) null_mask)) {
296
306
                        null_mask <<= 1;
297
307
                }
298
308
 
299
 
                if (UNIV_UNLIKELY(!field->fixed_len)) {
 
309
                if (!field->fixed_len
 
310
                    || (temp && !dict_col_get_fixed_size(col, temp))) {
300
311
                        /* Variable-length field: read the length */
301
 
                        const dict_col_t*       col
302
 
                                = dict_field_get_col(field);
303
312
                        len = *lens--;
304
313
                        /* If the maximum length of the field is up
305
314
                        to 255 bytes, the actual length is always
393
402
                                = dict_index_get_n_unique_in_tree(index);
394
403
                        break;
395
404
                case REC_STATUS_ORDINARY:
396
 
                        rec_init_offsets_comp_ordinary(rec,
397
 
                                                       REC_N_NEW_EXTRA_BYTES,
398
 
                                                       index, offsets);
 
405
                        rec_init_offsets_comp_ordinary(
 
406
                                rec, FALSE, index, offsets);
399
407
                        return;
400
408
                }
401
409
 
766
774
/**********************************************************//**
767
775
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
768
776
@return total size */
769
 
UNIV_INTERN
 
777
UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2)))
770
778
ulint
771
 
rec_get_converted_size_comp_prefix(
772
 
/*===============================*/
 
779
rec_get_converted_size_comp_prefix_low(
 
780
/*===================================*/
773
781
        const dict_index_t*     index,  /*!< in: record descriptor;
774
782
                                        dict_table_is_comp() is
775
783
                                        assumed to hold, even if
776
784
                                        it does not */
777
785
        const dfield_t*         fields, /*!< in: array of data fields */
778
786
        ulint                   n_fields,/*!< in: number of data fields */
779
 
        ulint*                  extra)  /*!< out: extra size */
 
787
        ulint*                  extra,  /*!< out: extra size */
 
788
        ibool                   temp)   /*!< in: whether this is a
 
789
                                        temporary file record */
780
790
{
781
791
        ulint   extra_size;
782
792
        ulint   data_size;
785
795
        ut_ad(fields);
786
796
        ut_ad(n_fields > 0);
787
797
        ut_ad(n_fields <= dict_index_get_n_fields(index));
 
798
        ut_ad(!temp || extra);
788
799
 
789
 
        extra_size = REC_N_NEW_EXTRA_BYTES
 
800
        extra_size = temp
 
801
                ? UT_BITS_IN_BYTES(index->n_nullable)
 
802
                : REC_N_NEW_EXTRA_BYTES
790
803
                + UT_BITS_IN_BYTES(index->n_nullable);
791
804
        data_size = 0;
792
805
 
 
806
        if (temp && dict_table_is_comp(index->table)) {
 
807
                /* No need to do adjust fixed_len=0. We only need to
 
808
                adjust it for ROW_FORMAT=REDUNDANT. */
 
809
                temp = FALSE;
 
810
        }
 
811
 
793
812
        /* read the lengths of fields 0..n */
794
813
        for (i = 0; i < n_fields; i++) {
795
814
                const dict_field_t*     field;
796
815
                ulint                   len;
 
816
                ulint                   fixed_len;
797
817
                const dict_col_t*       col;
798
818
 
799
819
                field = dict_index_get_nth_field(index, i);
809
829
                        continue;
810
830
                }
811
831
 
812
 
                ut_ad(len <= col->len || col->mtype == DATA_BLOB);
 
832
                ut_ad(len <= col->len || col->mtype == DATA_BLOB
 
833
                      || (col->len == 0 && col->mtype == DATA_VARCHAR));
813
834
 
 
835
                fixed_len = field->fixed_len;
 
836
                if (temp && fixed_len
 
837
                    && !dict_col_get_fixed_size(col, temp)) {
 
838
                        fixed_len = 0;
 
839
                }
814
840
                /* If the maximum length of a variable-length field
815
841
                is up to 255 bytes, the actual length is always stored
816
842
                in one byte. If the maximum length is more than 255
818
844
                0..127.  The length will be encoded in two bytes when
819
845
                it is 128 or more, or when the field is stored externally. */
820
846
 
821
 
                if (field->fixed_len) {
822
 
                        ut_ad(len == field->fixed_len);
 
847
                if (fixed_len) {
 
848
#ifdef UNIV_DEBUG
 
849
                        ulint   mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
 
850
                        ulint   mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
 
851
 
 
852
                        ut_ad(len <= fixed_len);
 
853
 
 
854
                        ut_ad(!mbmaxlen || len >= mbminlen
 
855
                              * (fixed_len / mbmaxlen));
 
856
 
823
857
                        /* dict_index_add_col() should guarantee this */
824
858
                        ut_ad(!field->prefix_len
825
 
                              || field->fixed_len == field->prefix_len);
 
859
                              || fixed_len == field->prefix_len);
 
860
#endif /* UNIV_DEBUG */
826
861
                } else if (dfield_is_ext(&fields[i])) {
827
862
                        ut_ad(col->len >= 256 || col->mtype == DATA_BLOB);
828
863
                        extra_size += 2;
839
874
                data_size += len;
840
875
        }
841
876
 
842
 
        if (UNIV_LIKELY_NULL(extra)) {
 
877
        if (extra) {
843
878
                *extra = extra_size;
844
879
        }
845
880
 
847
882
}
848
883
 
849
884
/**********************************************************//**
 
885
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
 
886
@return total size */
 
887
UNIV_INTERN
 
888
ulint
 
889
rec_get_converted_size_comp_prefix(
 
890
/*===============================*/
 
891
        const dict_index_t*     index,  /*!< in: record descriptor */
 
892
        const dfield_t*         fields, /*!< in: array of data fields */
 
893
        ulint                   n_fields,/*!< in: number of data fields */
 
894
        ulint*                  extra)  /*!< out: extra size */
 
895
{
 
896
        ut_ad(dict_table_is_comp(index->table));
 
897
        return(rec_get_converted_size_comp_prefix_low(
 
898
                       index, fields, n_fields, extra, FALSE));
 
899
}
 
900
 
 
901
/**********************************************************//**
850
902
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
851
903
@return total size */
852
904
UNIV_INTERN
890
942
                return(ULINT_UNDEFINED);
891
943
        }
892
944
 
893
 
        return(size + rec_get_converted_size_comp_prefix(index, fields,
894
 
                                                         n_fields, extra));
 
945
        return(size + rec_get_converted_size_comp_prefix_low(
 
946
                       index, fields, n_fields, extra, FALSE));
895
947
}
896
948
 
897
949
/***********************************************************//**
1068
1120
 
1069
1121
/*********************************************************//**
1070
1122
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
1071
 
UNIV_INTERN
 
1123
UNIV_INLINE __attribute__((nonnull))
1072
1124
void
1073
1125
rec_convert_dtuple_to_rec_comp(
1074
1126
/*===========================*/
1075
1127
        rec_t*                  rec,    /*!< in: origin of record */
1076
 
        ulint                   extra,  /*!< in: number of bytes to
1077
 
                                        reserve between the record
1078
 
                                        header and the data payload
1079
 
                                        (normally REC_N_NEW_EXTRA_BYTES) */
1080
1128
        const dict_index_t*     index,  /*!< in: record descriptor */
 
1129
        const dfield_t*         fields, /*!< in: array of data fields */
 
1130
        ulint                   n_fields,/*!< in: number of data fields */
1081
1131
        ulint                   status, /*!< in: status bits of the record */
1082
 
        const dfield_t*         fields, /*!< in: array of data fields */
1083
 
        ulint                   n_fields)/*!< in: number of data fields */
 
1132
        ibool                   temp)   /*!< in: whether to use the
 
1133
                                        format for temporary files in
 
1134
                                        index creation */
1084
1135
{
1085
1136
        const dfield_t* field;
1086
1137
        const dtype_t*  type;
1092
1143
        ulint           n_node_ptr_field;
1093
1144
        ulint           fixed_len;
1094
1145
        ulint           null_mask       = 1;
1095
 
        ut_ad(extra == 0 || dict_table_is_comp(index->table));
1096
 
        ut_ad(extra == 0 || extra == REC_N_NEW_EXTRA_BYTES);
 
1146
        ut_ad(temp || dict_table_is_comp(index->table));
1097
1147
        ut_ad(n_fields > 0);
1098
1148
 
1099
 
        switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
1100
 
        case REC_STATUS_ORDINARY:
 
1149
        if (temp) {
 
1150
                ut_ad(status == REC_STATUS_ORDINARY);
1101
1151
                ut_ad(n_fields <= dict_index_get_n_fields(index));
1102
1152
                n_node_ptr_field = ULINT_UNDEFINED;
1103
 
                break;
1104
 
        case REC_STATUS_NODE_PTR:
1105
 
                ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1);
1106
 
                n_node_ptr_field = n_fields - 1;
1107
 
                break;
1108
 
        case REC_STATUS_INFIMUM:
1109
 
        case REC_STATUS_SUPREMUM:
1110
 
                ut_ad(n_fields == 1);
1111
 
                n_node_ptr_field = ULINT_UNDEFINED;
1112
 
                break;
1113
 
        default:
1114
 
                ut_error;
1115
 
                return;
 
1153
                nulls = rec - 1;
 
1154
                if (dict_table_is_comp(index->table)) {
 
1155
                        /* No need to do adjust fixed_len=0. We only
 
1156
                        need to adjust it for ROW_FORMAT=REDUNDANT. */
 
1157
                        temp = FALSE;
 
1158
                }
 
1159
        } else {
 
1160
                nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
 
1161
 
 
1162
                switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
 
1163
                case REC_STATUS_ORDINARY:
 
1164
                        ut_ad(n_fields <= dict_index_get_n_fields(index));
 
1165
                        n_node_ptr_field = ULINT_UNDEFINED;
 
1166
                        break;
 
1167
                case REC_STATUS_NODE_PTR:
 
1168
                        ut_ad(n_fields
 
1169
                              == dict_index_get_n_unique_in_tree(index) + 1);
 
1170
                        n_node_ptr_field = n_fields - 1;
 
1171
                        break;
 
1172
                case REC_STATUS_INFIMUM:
 
1173
                case REC_STATUS_SUPREMUM:
 
1174
                        ut_ad(n_fields == 1);
 
1175
                        n_node_ptr_field = ULINT_UNDEFINED;
 
1176
                        break;
 
1177
                default:
 
1178
                        ut_error;
 
1179
                        return;
 
1180
                }
1116
1181
        }
1117
1182
 
1118
1183
        end = rec;
1119
 
        nulls = rec - (extra + 1);
1120
1184
        lens = nulls - UT_BITS_IN_BYTES(index->n_nullable);
1121
1185
        /* clear the SQL-null flags */
1122
1186
        memset(lens + 1, 0, nulls - lens);
1162
1226
 
1163
1227
                ifield = dict_index_get_nth_field(index, i);
1164
1228
                fixed_len = ifield->fixed_len;
 
1229
                if (temp && fixed_len
 
1230
                    && !dict_col_get_fixed_size(ifield->col, temp)) {
 
1231
                        fixed_len = 0;
 
1232
                }
1165
1233
                /* If the maximum length of a variable-length field
1166
1234
                is up to 255 bytes, the actual length is always stored
1167
1235
                in one byte. If the maximum length is more than 255
1169
1237
                0..127.  The length will be encoded in two bytes when
1170
1238
                it is 128 or more, or when the field is stored externally. */
1171
1239
                if (fixed_len) {
1172
 
                        ut_ad(len == fixed_len);
 
1240
#ifdef UNIV_DEBUG
 
1241
                        ulint   mbminlen = DATA_MBMINLEN(
 
1242
                                ifield->col->mbminmaxlen);
 
1243
                        ulint   mbmaxlen = DATA_MBMAXLEN(
 
1244
                                ifield->col->mbminmaxlen);
 
1245
 
 
1246
                        ut_ad(len <= fixed_len);
 
1247
                        ut_ad(!mbmaxlen || len >= mbminlen
 
1248
                              * (fixed_len / mbmaxlen));
1173
1249
                        ut_ad(!dfield_is_ext(field));
 
1250
#endif /* UNIV_DEBUG */
1174
1251
                } else if (dfield_is_ext(field)) {
1175
1252
                        ut_ad(ifield->col->len >= 256
1176
1253
                              || ifield->col->mtype == DATA_BLOB);
1222
1299
        rec = buf + extra_size;
1223
1300
 
1224
1301
        rec_convert_dtuple_to_rec_comp(
1225
 
                rec, REC_N_NEW_EXTRA_BYTES, index, status,
1226
 
                dtuple->fields, dtuple->n_fields);
 
1302
                rec, index, dtuple->fields, dtuple->n_fields, status, FALSE);
1227
1303
 
1228
1304
        /* Set the info bits of the record */
1229
1305
        rec_set_info_and_status_bits(rec, dtuple_get_info_bits(dtuple));
1285
1361
        return(rec);
1286
1362
}
1287
1363
 
 
1364
#ifndef UNIV_HOTBACKUP
 
1365
/**********************************************************//**
 
1366
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
 
1367
@return total size */
 
1368
UNIV_INTERN
 
1369
ulint
 
1370
rec_get_converted_size_temp(
 
1371
/*========================*/
 
1372
        const dict_index_t*     index,  /*!< in: record descriptor */
 
1373
        const dfield_t*         fields, /*!< in: array of data fields */
 
1374
        ulint                   n_fields,/*!< in: number of data fields */
 
1375
        ulint*                  extra)  /*!< out: extra size */
 
1376
{
 
1377
        return(rec_get_converted_size_comp_prefix_low(
 
1378
                       index, fields, n_fields, extra, TRUE));
 
1379
}
 
1380
 
 
1381
/******************************************************//**
 
1382
Determine the offset to each field in temporary file.
 
1383
@see rec_convert_dtuple_to_temp() */
 
1384
UNIV_INTERN
 
1385
void
 
1386
rec_init_offsets_temp(
 
1387
/*==================*/
 
1388
        const rec_t*            rec,    /*!< in: temporary file record */
 
1389
        const dict_index_t*     index,  /*!< in: record descriptor */
 
1390
        ulint*                  offsets)/*!< in/out: array of offsets;
 
1391
                                        in: n=rec_offs_n_fields(offsets) */
 
1392
{
 
1393
        rec_init_offsets_comp_ordinary(rec, TRUE, index, offsets);
 
1394
}
 
1395
 
 
1396
/*********************************************************//**
 
1397
Builds a temporary file record out of a data tuple.
 
1398
@see rec_init_offsets_temp() */
 
1399
UNIV_INTERN
 
1400
void
 
1401
rec_convert_dtuple_to_temp(
 
1402
/*=======================*/
 
1403
        rec_t*                  rec,            /*!< out: record */
 
1404
        const dict_index_t*     index,          /*!< in: record descriptor */
 
1405
        const dfield_t*         fields,         /*!< in: array of data fields */
 
1406
        ulint                   n_fields)       /*!< in: number of fields */
 
1407
{
 
1408
        rec_convert_dtuple_to_rec_comp(rec, index, fields, n_fields,
 
1409
                                       REC_STATUS_ORDINARY, TRUE);
 
1410
}
 
1411
 
1288
1412
/**************************************************************//**
1289
1413
Copies the first n fields of a physical record to a data tuple. The fields
1290
1414
are copied to the memory heap. */
1495
1619
 
1496
1620
        return(*buf + (rec - (lens + 1)));
1497
1621
}
 
1622
#endif /* UNIV_HOTBACKUP */
1498
1623
 
1499
1624
/***************************************************************//**
1500
1625
Validates the consistency of an old-style physical record.