@@ -1101,77 +1101,6 @@ static inline enum REC_INSERT_STATE rec_init_null_and_len_comp(
1101
1101
return (rec_insert_state);
1102
1102
}
1103
1103
1104
- /* *
1105
- Determine the offset of the given field
1106
-
1107
- @param[in] field Field whose length and offset is determined
1108
- @param[in] index Index to which field belongs
1109
- @param[in] temp True for temp record
1110
- @param[in,out] n_null Number of nullable columns in record
1111
- @param[in,out] null_mask Mask of null bitmap
1112
- @param[in,out] nulls Pointer to null bitmap of the record
1113
- @param[in,out] lens Pointer to lens in the record
1114
- @param[in,out] offs Offset of current field, updated to next field
1115
- @param[in,out] any_ext Offset to indicate presence of extern col
1116
-
1117
- @return offset Offset of the field
1118
- */
1119
- static inline uint64_t calculate_field_offset (
1120
- const dict_field_t *field,
1121
- IF_DEBUG (const dict_index_t *index, ) const bool temp, uint16_t &n_null,
1122
- ulint &null_mask, const byte *&nulls, const byte *&lens, ulint &offs,
1123
- ulint &any_ext) {
1124
- /* Fields are stored on disk in version they are added in and are maintained
1125
- in fields_array in the same order. Get the right field. */
1126
- const dict_col_t *col = field->col ;
1127
-
1128
- if (!(col->prtype & DATA_NOT_NULL)) {
1129
- /* nullable field => read the null flag */
1130
- ut_ad (n_null--);
1131
-
1132
- if (UNIV_UNLIKELY (!(byte)null_mask)) {
1133
- nulls--;
1134
- null_mask = 1 ;
1135
- }
1136
-
1137
- if (*nulls & null_mask) {
1138
- null_mask <<= 1 ;
1139
- /* No length is stored for NULL fields. We do not advance offs, and we set
1140
- the length to zero and enable the SQL NULL flag in offsets[]. */
1141
- return (offs | REC_OFFS_SQL_NULL);
1142
- }
1143
- null_mask <<= 1 ;
1144
- }
1145
-
1146
- if (!field->fixed_len || (temp && !col->get_fixed_size (temp))) {
1147
- ut_ad (col->mtype != DATA_POINT);
1148
- /* Variable-length field: read the length */
1149
- uint64_t len = *lens--;
1150
- /* If the maximum length of the field is up to 255 bytes, the actual length
1151
- is always stored in one byte. If the maximum length is more than 255 bytes,
1152
- the actual length is stored in one byte for 0..127. The length will be
1153
- encoded in two bytes when it is 128 or more, or when the field is stored
1154
- externally. */
1155
- if (DATA_BIG_COL (col)) {
1156
- if (len & 0x80 ) {
1157
- /* 1exxxxxxx xxxxxxxx */
1158
- len <<= 8 ;
1159
- len |= *lens--;
1160
-
1161
- offs += len & 0x3fff ;
1162
- if (UNIV_UNLIKELY (len & 0x4000 )) {
1163
- ut_ad (index ->is_clustered ());
1164
- any_ext = REC_OFFS_EXTERNAL;
1165
- return (offs | REC_OFFS_EXTERNAL);
1166
- }
1167
- return offs;
1168
- }
1169
- }
1170
- return (offs += len);
1171
- }
1172
- return (offs += field->fixed_len );
1173
- }
1174
-
1175
1104
/* * Determine the offset to each field in a leaf-page record in
1176
1105
ROW_FORMAT=COMPACT. This is a special case of rec_init_offsets() and
1177
1106
rec_get_offsets().
@@ -1230,34 +1159,25 @@ inline void rec_init_offsets_comp_ordinary(const rec_t *rec, bool temp,
1230
1159
ulint any_ext = 0 ;
1231
1160
ulint null_mask = 1 ;
1232
1161
uint16_t i = 0 ;
1233
-
1234
- if (rec_insert_state == INSERTED_INTO_TABLE_WITH_NO_INSTANT_NO_VERSION) {
1235
- ut_ad (!index ->has_instant_cols_or_row_versions ());
1236
- do {
1237
- const dict_field_t *field = index ->get_physical_field (i);
1238
- rec_offs_base (offsets)[i + 1 ] =
1239
- calculate_field_offset (field, IF_DEBUG (index , ) temp, n_null,
1240
- null_mask, nulls, lens, offs, any_ext);
1241
- } while (++i < rec_offs_n_fields (offsets));
1242
-
1243
- *rec_offs_base (offsets) = (rec - (lens + 1 )) | REC_OFFS_COMPACT | any_ext;
1244
- return ;
1245
- }
1246
-
1247
- /* This record belongs to a table which has at least one INSTANT ADD/DROP done
1248
- */
1249
- if (rec_insert_state == INSERTED_BEFORE_INSTANT_ADD_NEW_IMPLEMENTATION) {
1250
- ut_ad (row_version == INVALID_ROW_VERSION || row_version == 0 );
1251
- ut_ad (index ->has_row_versions () || temp);
1252
- /* Record has to be interpreted in v0. */
1253
- row_version = 0 ;
1254
- }
1255
-
1256
1162
do {
1163
+ /* Fields are stored on disk in version they are added in and are
1164
+ maintained in fields_array in the same order. Get the right field. */
1257
1165
const dict_field_t *field = index ->get_physical_field (i);
1258
1166
const dict_col_t *col = field->col ;
1167
+ uint64_t len;
1168
+
1259
1169
switch (rec_insert_state) {
1260
- case INSERTED_BEFORE_INSTANT_ADD_NEW_IMPLEMENTATION:
1170
+ case INSERTED_INTO_TABLE_WITH_NO_INSTANT_NO_VERSION:
1171
+ ut_ad (!index ->has_instant_cols_or_row_versions ());
1172
+ break ;
1173
+
1174
+ case INSERTED_BEFORE_INSTANT_ADD_NEW_IMPLEMENTATION: {
1175
+ ut_ad (row_version == INVALID_ROW_VERSION || row_version == 0 );
1176
+ ut_ad (index ->has_row_versions () || temp);
1177
+ /* Record has to be interpreted in v0. */
1178
+ row_version = 0 ;
1179
+ }
1180
+ [[fallthrough]];
1261
1181
case INSERTED_AFTER_UPGRADE_BEFORE_INSTANT_ADD_NEW_IMPLEMENTATION:
1262
1182
case INSERTED_AFTER_INSTANT_ADD_NEW_IMPLEMENTATION: {
1263
1183
ut_ad (is_valid_row_version (row_version));
@@ -1269,22 +1189,21 @@ inline void rec_init_offsets_comp_ordinary(const rec_t *rec, bool temp,
1269
1189
column is there in this record or not. */
1270
1190
if (col->is_dropped_in_or_before (row_version)) {
1271
1191
/* This columns is dropped before or on this row version so its data
1272
- won't be there on row. So no need to store the length. Instead,
1273
- store offs ORed with REC_OFFS_DROP to indicate the same. */
1274
- rec_offs_base (offsets)[i + 1 ] = (offs | REC_OFFS_DROP);
1275
- continue ;
1276
-
1277
- /* NOTE : Existing rows, which have data for this column, would
1278
- still need to process this column, so don't skip and store the
1279
- correct length there. Though it will be skipped while fetching row.
1280
- */
1192
+ won't be there on row. So no need to store the length. Instead, store
1193
+ offs ORed with REC_OFFS_DROP to indicate the same. */
1194
+ len = offs | REC_OFFS_DROP;
1195
+ goto resolved;
1196
+
1197
+ /* NOTE : Existing rows, which have data for this column, would still
1198
+ need to process this column, so don't skip and store the correct
1199
+ length there. Though it will be skipped while fetching row. */
1281
1200
} else if (col->is_added_after (row_version)) {
1282
- /* This columns is added after this row version. In this case no
1283
- need to store the length. Instead store only if it is NULL or
1284
- DEFAULT value. */
1285
- rec_offs_base (offsets)[i + 1 ] =
1286
- rec_get_instant_offset ( index , i, offs);
1287
- continue ;
1201
+ /* This columns is added after this row version. In this case no need
1202
+ to store the length. Instead store only if it is NULL or DEFAULT
1203
+ value. */
1204
+ len = rec_get_instant_offset ( index , i, offs);
1205
+
1206
+ goto resolved ;
1288
1207
}
1289
1208
} break ;
1290
1209
@@ -1298,9 +1217,9 @@ inline void rec_init_offsets_comp_ordinary(const rec_t *rec, bool temp,
1298
1217
/* This would be the case when column doesn't exists in the row. In
1299
1218
this case we need not to store the length. Instead we store only if
1300
1219
the column is NULL or DEFAULT value. */
1301
- rec_offs_base (offsets)[i + 1 ] =
1302
- rec_get_instant_offset ( index , i, offs);
1303
- continue ;
1220
+ len = rec_get_instant_offset ( index , i, offs);
1221
+
1222
+ goto resolved ;
1304
1223
}
1305
1224
1306
1225
/* Note : Even if the column has been dropped, this row in V1 would
@@ -1310,9 +1229,64 @@ inline void rec_init_offsets_comp_ordinary(const rec_t *rec, bool temp,
1310
1229
default :
1311
1230
ut_ad (false );
1312
1231
}
1313
- rec_offs_base (offsets)[i + 1 ] =
1314
- calculate_field_offset (field, IF_DEBUG (index , ) temp, n_null, null_mask,
1315
- nulls, lens, offs, any_ext);
1232
+
1233
+ if (!(col->prtype & DATA_NOT_NULL)) {
1234
+ /* nullable field => read the null flag */
1235
+ ut_ad (n_null--);
1236
+
1237
+ if (UNIV_UNLIKELY (!(byte)null_mask)) {
1238
+ nulls--;
1239
+ null_mask = 1 ;
1240
+ }
1241
+
1242
+ if (*nulls & null_mask) {
1243
+ null_mask <<= 1 ;
1244
+ /* No length is stored for NULL fields.
1245
+ We do not advance offs, and we set
1246
+ the length to zero and enable the
1247
+ SQL NULL flag in offsets[]. */
1248
+ len = offs | REC_OFFS_SQL_NULL;
1249
+ goto resolved;
1250
+ }
1251
+ null_mask <<= 1 ;
1252
+ }
1253
+
1254
+ if (!field->fixed_len || (temp && !col->get_fixed_size (temp))) {
1255
+ ut_ad (col->mtype != DATA_POINT);
1256
+ /* Variable-length field: read the length */
1257
+ len = *lens--;
1258
+ /* If the maximum length of the field is up
1259
+ to 255 bytes, the actual length is always
1260
+ stored in one byte. If the maximum length is
1261
+ more than 255 bytes, the actual length is
1262
+ stored in one byte for 0..127. The length
1263
+ will be encoded in two bytes when it is 128 or
1264
+ more, or when the field is stored externally. */
1265
+ if (DATA_BIG_COL (col)) {
1266
+ if (len & 0x80 ) {
1267
+ /* 1exxxxxxx xxxxxxxx */
1268
+ len <<= 8 ;
1269
+ len |= *lens--;
1270
+
1271
+ offs += len & 0x3fff ;
1272
+ if (UNIV_UNLIKELY (len & 0x4000 )) {
1273
+ ut_ad (index ->is_clustered ());
1274
+ any_ext = REC_OFFS_EXTERNAL;
1275
+ len = offs | REC_OFFS_EXTERNAL;
1276
+ } else {
1277
+ len = offs;
1278
+ }
1279
+
1280
+ goto resolved;
1281
+ }
1282
+ }
1283
+
1284
+ len = offs += len;
1285
+ } else {
1286
+ len = offs += field->fixed_len ;
1287
+ }
1288
+ resolved:
1289
+ rec_offs_base (offsets)[i + 1 ] = len;
1316
1290
} while (++i < rec_offs_n_fields (offsets));
1317
1291
1318
1292
*rec_offs_base (offsets) = (rec - (lens + 1 )) | REC_OFFS_COMPACT | any_ext;
0 commit comments