189
188
/* read the lengths of fields 0..n */
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);
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 */
197
199
if (UNIV_UNLIKELY(!(byte) null_mask)) {
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);
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_INLINE __attribute__((nonnull))
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
251
(usually REC_N_NEW_EXTRA_BYTES) */
248
ibool temp, /*!< in: whether to use the
249
format for temporary files in
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) */
258
257
ulint any_ext = 0;
259
const byte* nulls = rec - (extra + 1);
258
const byte* nulls = temp
260
: rec - (1 + REC_N_NEW_EXTRA_BYTES);
260
261
const byte* lens = nulls
261
262
- UT_BITS_IN_BYTES(index->n_nullable);
263
263
ulint null_mask = 1;
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 */
273
ut_ad(temp || dict_table_is_comp(index->table));
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. */
273
281
/* read the lengths of fields 0..n */
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);
277
field = dict_index_get_nth_field(index, i);
278
if (!(dict_field_get_col(field)->prtype
289
if (!(col->prtype & DATA_NOT_NULL)) {
280
290
/* nullable field => read the null flag */
282
292
if (UNIV_UNLIKELY(!(byte) null_mask)) {
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);
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);
395
404
case REC_STATUS_ORDINARY:
396
rec_init_offsets_comp_ordinary(rec,
397
REC_N_NEW_EXTRA_BYTES,
405
rec_init_offsets_comp_ordinary(
406
rec, FALSE, index, offsets);
766
774
/**********************************************************//**
767
775
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
768
776
@return total size */
777
UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2)))
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
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 */
781
791
ulint extra_size;
786
796
ut_ad(n_fields > 0);
787
797
ut_ad(n_fields <= dict_index_get_n_fields(index));
798
ut_ad(!temp || extra);
789
extra_size = REC_N_NEW_EXTRA_BYTES
801
? UT_BITS_IN_BYTES(index->n_nullable)
802
: REC_N_NEW_EXTRA_BYTES
790
803
+ UT_BITS_IN_BYTES(index->n_nullable);
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. */
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;
797
817
const dict_col_t* col;
799
819
field = dict_index_get_nth_field(index, i);
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));
835
fixed_len = field->fixed_len;
836
if (temp && fixed_len
837
&& !dict_col_get_fixed_size(col, temp)) {
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. */
821
if (field->fixed_len) {
822
ut_ad(len == field->fixed_len);
849
ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
850
ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
852
ut_ad(len <= fixed_len);
854
ut_ad(!mbmaxlen || len >= mbminlen
855
* (fixed_len / mbmaxlen));
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);
849
884
/**********************************************************//**
885
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
886
@return total size */
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 */
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));
901
/**********************************************************//**
850
902
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
851
903
@return total size */
890
942
return(ULINT_UNDEFINED);
893
return(size + rec_get_converted_size_comp_prefix(index, fields,
945
return(size + rec_get_converted_size_comp_prefix_low(
946
index, fields, n_fields, extra, FALSE));
897
949
/***********************************************************//**
1069
1121
/*********************************************************//**
1070
1122
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
1123
UNIV_INLINE __attribute__((nonnull))
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
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);
1099
switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
1100
case REC_STATUS_ORDINARY:
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;
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;
1108
case REC_STATUS_INFIMUM:
1109
case REC_STATUS_SUPREMUM:
1110
ut_ad(n_fields == 1);
1111
n_node_ptr_field = ULINT_UNDEFINED;
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. */
1160
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
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;
1167
case REC_STATUS_NODE_PTR:
1169
== dict_index_get_n_unique_in_tree(index) + 1);
1170
n_node_ptr_field = n_fields - 1;
1172
case REC_STATUS_INFIMUM:
1173
case REC_STATUS_SUPREMUM:
1174
ut_ad(n_fields == 1);
1175
n_node_ptr_field = ULINT_UNDEFINED;
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);
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)) {
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);
1241
ulint mbminlen = DATA_MBMINLEN(
1242
ifield->col->mbminmaxlen);
1243
ulint mbmaxlen = DATA_MBMAXLEN(
1244
ifield->col->mbminmaxlen);
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;
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);
1228
1304
/* Set the info bits of the record */
1229
1305
rec_set_info_and_status_bits(rec, dtuple_get_info_bits(dtuple));
1364
#ifndef UNIV_HOTBACKUP
1365
/**********************************************************//**
1366
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
1367
@return total size */
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 */
1377
return(rec_get_converted_size_comp_prefix_low(
1378
index, fields, n_fields, extra, TRUE));
1381
/******************************************************//**
1382
Determine the offset to each field in temporary file.
1383
@see rec_convert_dtuple_to_temp() */
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) */
1393
rec_init_offsets_comp_ordinary(rec, TRUE, index, offsets);
1396
/*********************************************************//**
1397
Builds a temporary file record out of a data tuple.
1398
@see rec_init_offsets_temp() */
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 */
1408
rec_convert_dtuple_to_rec_comp(rec, index, fields, n_fields,
1409
REC_STATUS_ORDINARY, TRUE);
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. */