24
22
#include "trx0purge.h"
25
23
#include "trx0rec.h"
26
24
#include "que0que.h"
28
26
#include "row0upd.h"
29
27
#include "rem0cmp.h"
30
28
#include "read0read.h"
33
30
/*************************************************************************
34
Gets the offset of trx id field, in bytes relative to the origin of
35
a clustered index record. */
38
row_get_trx_id_offset(
31
Reads the trx id or roll ptr field from a clustered index record: this function
32
is slower than the specialized inline functions. */
35
row_get_rec_sys_field(
39
36
/*==================*/
40
/* out: offset of DATA_TRX_ID */
41
const rec_t* rec __attribute__((unused)),
37
/* out: value of the field */
38
ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
39
rec_t* rec, /* in: record */
43
40
dict_index_t* index, /* in: clustered index */
44
41
const ulint* offsets)/* in: rec_get_offsets(rec, index) */
47
ut_ad(index->type & DICT_CLUSTERED);
49
pos = dict_index_get_sys_col_pos(index, type);
51
field = rec_get_nth_field(rec, offsets, pos, &len);
53
if (type == DATA_TRX_ID) {
55
return(trx_read_trx_id(field));
57
ut_ad(type == DATA_ROLL_PTR);
59
return(trx_read_roll_ptr(field));
63
/*************************************************************************
64
Sets the trx id or roll ptr field in a clustered index record: this function
65
is slower than the specialized inline functions. */
68
row_set_rec_sys_field(
69
/*==================*/
70
/* out: value of the field */
71
ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
72
rec_t* rec, /* in: record */
73
dict_index_t* index, /* in: clustered index */
74
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
75
dulint val) /* in: value to set */
50
ut_ad(dict_index_is_clust(index));
81
ut_ad(index->type & DICT_CLUSTERED);
51
82
ut_ad(rec_offs_validate(rec, index, offsets));
53
pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID);
55
offset = rec_get_nth_field_offs(offsets, pos, &len);
57
ut_ad(len == DATA_TRX_ID_LEN);
84
pos = dict_index_get_sys_col_pos(index, type);
86
field = rec_get_nth_field(rec, offsets, pos, &len);
88
if (type == DATA_TRX_ID) {
90
trx_write_trx_id(field, val);
92
ut_ad(type == DATA_ROLL_PTR);
94
trx_write_roll_ptr(field, val);
62
98
/*********************************************************************
63
When an insert or purge to a table is performed, this function builds
64
the entry to be inserted into or purged from an index on the table. */
99
When an insert to a table is performed, this function builds the entry which
100
has to be inserted to an index on the table. */
67
103
row_build_index_entry(
68
104
/*==================*/
69
/* out: index entry which should be
70
inserted or purged, or NULL if the
71
externally stored columns in the
72
clustered index record are unavailable
74
const dtuple_t* row, /* in: row which should be
76
row_ext_t* ext, /* in: externally stored column prefixes,
105
/* out: index entry which should be inserted */
106
dtuple_t* row, /* in: row which should be inserted to the
78
108
dict_index_t* index, /* in: index on the table */
79
109
mem_heap_t* heap) /* in: memory heap from which the memory for
80
110
the index entry is allocated */
114
dict_field_t* ind_field;
86
120
ut_ad(row && index && heap);
87
121
ut_ad(dtuple_check_typed(row));
810
712
n_fields = dtuple_get_n_fields(entry);
812
return(!page_rec_is_infimum(rec) && low_match == n_fields);
815
#ifndef UNIV_HOTBACKUP
817
#if defined(BUILD_DRIZZLE)
818
# include <mysys/my_sys.h>
823
/***********************************************************************
824
Formats the raw data in "data" (in InnoDB on-disk format) that is of
825
type DATA_INT using "prtype" and writes the result to "buf".
826
If the data is in unknown format, then nothing is written to "buf",
827
0 is returned and "format_in_hex" is set to TRUE, otherwise
828
"format_in_hex" is left untouched.
829
Not more than "buf_size" bytes are written to "buf".
830
The result is always '\0'-terminated (provided buf_size > 0) and the
831
number of bytes that were written to "buf" is returned (including the
832
terminating '\0'). */
837
/* out: number of bytes
839
const char* data, /* in: raw data */
840
ulint data_len, /* in: raw data length
842
ulint prtype, /* in: precise type */
843
char* buf, /* out: output buffer */
844
ulint buf_size, /* in: output buffer size
846
ibool* format_in_hex) /* out: should the data be
851
if (data_len <= sizeof(ullint)) {
854
ibool unsigned_type = prtype & DATA_UNSIGNED;
856
value = mach_read_int_type((const byte*) data,
857
data_len, unsigned_type);
861
ret = ut_snprintf(buf, buf_size, "%llu",
865
ret = ut_snprintf(buf, buf_size, "%lld",
866
(long long) value) + 1;
871
*format_in_hex = TRUE;
875
return(ut_min(ret, buf_size));
878
/***********************************************************************
879
Formats the raw data in "data" (in InnoDB on-disk format) that is of
880
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "prtype" and writes the
882
If the data is in binary format, then nothing is written to "buf",
883
0 is returned and "format_in_hex" is set to TRUE, otherwise
884
"format_in_hex" is left untouched.
885
Not more than "buf_size" bytes are written to "buf".
886
The result is always '\0'-terminated (provided buf_size > 0) and the
887
number of bytes that were written to "buf" is returned (including the
888
terminating '\0'). */
893
/* out: number of bytes
895
const char* data, /* in: raw data */
896
ulint data_len, /* in: raw data length
898
ulint prtype, /* in: precise type */
899
char* buf, /* out: output buffer */
900
ulint buf_size, /* in: output buffer size
902
ibool* format_in_hex) /* out: should the data be
912
/* we assume system_charset_info is UTF-8 */
914
charset_coll = dtype_get_charset_coll(prtype);
916
if (UNIV_LIKELY(dtype_is_utf8(prtype))) {
918
return(ut_str_sql_format(data, data_len, buf, buf_size));
922
if (charset_coll == DATA_MYSQL_BINARY_CHARSET_COLL) {
924
*format_in_hex = TRUE;
929
return(innobase_raw_format(data, data_len, charset_coll,
933
/***********************************************************************
934
Formats the raw data in "data" (in InnoDB on-disk format) using
935
"dict_field" and writes the result to "buf".
936
Not more than "buf_size" bytes are written to "buf".
937
The result is always '\0'-terminated (provided buf_size > 0) and the
938
number of bytes that were written to "buf" is returned (including the
939
terminating '\0'). */
944
/* out: number of bytes
946
const char* data, /* in: raw data */
947
ulint data_len, /* in: raw data length
949
const dict_field_t* dict_field, /* in: index field */
950
char* buf, /* out: output buffer */
951
ulint buf_size) /* in: output buffer size
964
if (data_len == UNIV_SQL_NULL) {
966
ret = ut_snprintf((char*) buf, buf_size, "NULL") + 1;
968
return(ut_min(ret, buf_size));
971
mtype = dict_field->col->mtype;
972
prtype = dict_field->col->prtype;
974
format_in_hex = FALSE;
979
ret = row_raw_format_int(data, data_len, prtype,
980
buf, buf_size, &format_in_hex);
987
ret = row_raw_format_str(data, data_len, prtype,
988
buf, buf_size, &format_in_hex);
990
/* XXX support more data types */
993
format_in_hex = TRUE;
998
if (UNIV_LIKELY(buf_size > 2)) {
1000
memcpy(buf, "0x", 2);
1003
ret = 2 + ut_raw_to_hex(data, data_len,
1015
#endif /* !UNIV_HOTBACKUP */
1017
#ifdef UNIV_COMPILE_TEST_FUNCS
1022
test_row_raw_format_int()
1026
ibool format_in_hex;
1028
#define CALL_AND_TEST(data, data_len, prtype, buf, buf_size,\
1029
ret_expected, buf_expected, format_in_hex_expected)\
1033
memset(buf, 'x', 10);\
1035
format_in_hex = FALSE;\
1036
fprintf(stderr, "TESTING \"\\x");\
1037
for (i = 0; i < data_len; i++) {\
1038
fprintf(stderr, "%02hhX", data[i]);\
1040
fprintf(stderr, "\", %lu, %lu, %lu\n",\
1041
(ulint) data_len, (ulint) prtype,\
1043
ret = row_raw_format_int(data, data_len, prtype,\
1044
buf, buf_size, &format_in_hex);\
1045
if (ret != ret_expected) {\
1046
fprintf(stderr, "expected ret %lu, got %lu\n",\
1047
(ulint) ret_expected, ret);\
1050
if (strcmp((char*) buf, buf_expected) != 0) {\
1051
fprintf(stderr, "expected buf \"%s\", got \"%s\"\n",\
1052
buf_expected, buf);\
1055
if (format_in_hex != format_in_hex_expected) {\
1056
fprintf(stderr, "expected format_in_hex %d, got %d\n",\
1057
(int) format_in_hex_expected,\
1058
(int) format_in_hex);\
1062
fprintf(stderr, "OK: %lu, \"%s\" %d\n\n",\
1063
(ulint) ret, buf, (int) format_in_hex);\
1070
/* min values for signed 1-8 byte integers */
1072
CALL_AND_TEST("\x00", 1, 0,
1073
buf, sizeof(buf), 5, "-128", 0);
1075
CALL_AND_TEST("\x00\x00", 2, 0,
1076
buf, sizeof(buf), 7, "-32768", 0);
1078
CALL_AND_TEST("\x00\x00\x00", 3, 0,
1079
buf, sizeof(buf), 9, "-8388608", 0);
1081
CALL_AND_TEST("\x00\x00\x00\x00", 4, 0,
1082
buf, sizeof(buf), 12, "-2147483648", 0);
1084
CALL_AND_TEST("\x00\x00\x00\x00\x00", 5, 0,
1085
buf, sizeof(buf), 14, "-549755813888", 0);
1087
CALL_AND_TEST("\x00\x00\x00\x00\x00\x00", 6, 0,
1088
buf, sizeof(buf), 17, "-140737488355328", 0);
1090
CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00", 7, 0,
1091
buf, sizeof(buf), 19, "-36028797018963968", 0);
1093
CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00\x00", 8, 0,
1094
buf, sizeof(buf), 21, "-9223372036854775808", 0);
1096
/* min values for unsigned 1-8 byte integers */
1098
CALL_AND_TEST("\x00", 1, DATA_UNSIGNED,
1099
buf, sizeof(buf), 2, "0", 0);
1101
CALL_AND_TEST("\x00\x00", 2, DATA_UNSIGNED,
1102
buf, sizeof(buf), 2, "0", 0);
1104
CALL_AND_TEST("\x00\x00\x00", 3, DATA_UNSIGNED,
1105
buf, sizeof(buf), 2, "0", 0);
1107
CALL_AND_TEST("\x00\x00\x00\x00", 4, DATA_UNSIGNED,
1108
buf, sizeof(buf), 2, "0", 0);
1110
CALL_AND_TEST("\x00\x00\x00\x00\x00", 5, DATA_UNSIGNED,
1111
buf, sizeof(buf), 2, "0", 0);
1113
CALL_AND_TEST("\x00\x00\x00\x00\x00\x00", 6, DATA_UNSIGNED,
1114
buf, sizeof(buf), 2, "0", 0);
1116
CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00", 7, DATA_UNSIGNED,
1117
buf, sizeof(buf), 2, "0", 0);
1119
CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00\x00", 8, DATA_UNSIGNED,
1120
buf, sizeof(buf), 2, "0", 0);
1122
/* max values for signed 1-8 byte integers */
1124
CALL_AND_TEST("\xFF", 1, 0,
1125
buf, sizeof(buf), 4, "127", 0);
1127
CALL_AND_TEST("\xFF\xFF", 2, 0,
1128
buf, sizeof(buf), 6, "32767", 0);
1130
CALL_AND_TEST("\xFF\xFF\xFF", 3, 0,
1131
buf, sizeof(buf), 8, "8388607", 0);
1133
CALL_AND_TEST("\xFF\xFF\xFF\xFF", 4, 0,
1134
buf, sizeof(buf), 11, "2147483647", 0);
1136
CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF", 5, 0,
1137
buf, sizeof(buf), 13, "549755813887", 0);
1139
CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF", 6, 0,
1140
buf, sizeof(buf), 16, "140737488355327", 0);
1142
CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 7, 0,
1143
buf, sizeof(buf), 18, "36028797018963967", 0);
1145
CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8, 0,
1146
buf, sizeof(buf), 20, "9223372036854775807", 0);
1148
/* max values for unsigned 1-8 byte integers */
1150
CALL_AND_TEST("\xFF", 1, DATA_UNSIGNED,
1151
buf, sizeof(buf), 4, "255", 0);
1153
CALL_AND_TEST("\xFF\xFF", 2, DATA_UNSIGNED,
1154
buf, sizeof(buf), 6, "65535", 0);
1156
CALL_AND_TEST("\xFF\xFF\xFF", 3, DATA_UNSIGNED,
1157
buf, sizeof(buf), 9, "16777215", 0);
1159
CALL_AND_TEST("\xFF\xFF\xFF\xFF", 4, DATA_UNSIGNED,
1160
buf, sizeof(buf), 11, "4294967295", 0);
1162
CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF", 5, DATA_UNSIGNED,
1163
buf, sizeof(buf), 14, "1099511627775", 0);
1165
CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF", 6, DATA_UNSIGNED,
1166
buf, sizeof(buf), 16, "281474976710655", 0);
1168
CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 7, DATA_UNSIGNED,
1169
buf, sizeof(buf), 18, "72057594037927935", 0);
1171
CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8, DATA_UNSIGNED,
1172
buf, sizeof(buf), 21, "18446744073709551615", 0);
1174
/* some random values */
1176
CALL_AND_TEST("\x52", 1, 0,
1177
buf, sizeof(buf), 4, "-46", 0);
1179
CALL_AND_TEST("\x0E", 1, DATA_UNSIGNED,
1180
buf, sizeof(buf), 3, "14", 0);
1182
CALL_AND_TEST("\x62\xCE", 2, 0,
1183
buf, sizeof(buf), 6, "-7474", 0);
1185
CALL_AND_TEST("\x29\xD6", 2, DATA_UNSIGNED,
1186
buf, sizeof(buf), 6, "10710", 0);
1188
CALL_AND_TEST("\x7F\xFF\x90", 3, 0,
1189
buf, sizeof(buf), 5, "-112", 0);
1191
CALL_AND_TEST("\x00\xA1\x16", 3, DATA_UNSIGNED,
1192
buf, sizeof(buf), 6, "41238", 0);
1194
CALL_AND_TEST("\x7F\xFF\xFF\xF7", 4, 0,
1195
buf, sizeof(buf), 3, "-9", 0);
1197
CALL_AND_TEST("\x00\x00\x00\x5C", 4, DATA_UNSIGNED,
1198
buf, sizeof(buf), 3, "92", 0);
1200
CALL_AND_TEST("\x7F\xFF\xFF\xFF\xFF\xFF\xDC\x63", 8, 0,
1201
buf, sizeof(buf), 6, "-9117", 0);
1203
CALL_AND_TEST("\x00\x00\x00\x00\x00\x01\x64\x62", 8, DATA_UNSIGNED,
1204
buf, sizeof(buf), 6, "91234", 0);
1212
speedo_reset(&speedo);
1214
for (i = 0; i < 1000000; i++) {
1215
row_raw_format_int("\x23", 1,
1216
0, buf, sizeof(buf),
1218
row_raw_format_int("\x23", 1,
1219
DATA_UNSIGNED, buf, sizeof(buf),
1222
row_raw_format_int("\x00\x00\x00\x00\x00\x01\x64\x62", 8,
1223
0, buf, sizeof(buf),
1225
row_raw_format_int("\x00\x00\x00\x00\x00\x01\x64\x62", 8,
1226
DATA_UNSIGNED, buf, sizeof(buf),
1230
speedo_show(&speedo);
1233
#endif /* UNIV_COMPILE_TEST_FUNCS */
714
if (page_rec_is_infimum(rec)) {
719
if (low_match != n_fields) {