/**********************************************************************//** Reads from an undo log update record the system field values of the old version. @return remaining part of undo log record after reading these values */ UNIV_INTERN byte* trx_undo_update_rec_get_sys_cols( /*=============================*/ byte* ptr, /*!< in: remaining part of undo log record after reading general parameters */ trx_id_t* trx_id, /*!< out: trx id */ roll_ptr_t* roll_ptr, /*!< out: roll ptr */ ulint* info_bits) /*!< out: info bits state */ { /* Read the state of the info bits */ *info_bits = mach_read_from_1(ptr); ptr += 1; /* Read the values of the system columns */ *trx_id = mach_dulint_read_compressed(ptr); ptr += mach_dulint_get_compressed_size(*trx_id); *roll_ptr = mach_dulint_read_compressed(ptr); ptr += mach_dulint_get_compressed_size(*roll_ptr); return(ptr); }
byte* mach_parse_compressed( /*==================*/ /* out: pointer to end of the stored field, NULL if not complete */ byte* ptr, /* in: pointer to buffer from where to read */ byte* end_ptr,/* in: pointer to end of the buffer */ ulint* val) /* out: read value (< 2^32) */ { ulint flag; ut_ad(ptr && end_ptr && val); if (ptr >= end_ptr) { return(NULL); } flag = mach_read_from_1(ptr); if (flag < 0x80UL) { *val = flag; return(ptr + 1); } else if (flag < 0xC0UL) { if (end_ptr < ptr + 2) { return(NULL); } *val = mach_read_from_2(ptr) & 0x7FFFUL; return(ptr + 2); } else if (flag < 0xE0UL) { if (end_ptr < ptr + 3) { return(NULL); } *val = mach_read_from_3(ptr) & 0x3FFFFFUL; return(ptr + 3); } else if (flag < 0xF0UL) { if (end_ptr < ptr + 4) { return(NULL); } *val = mach_read_from_4(ptr) & 0x1FFFFFFFUL; return(ptr + 4); } else { ut_ad(flag == 0xF0UL); if (end_ptr < ptr + 5) { return(NULL); } *val = mach_read_from_4(ptr + 1); return(ptr + 5); } }
inline long long int get_int_value(field_def_t *field, byte *value) { switch (field->fixed_length) { case 1: return mach_read_from_1(value) & ~(1<<7); case 2: return mach_read_from_2(value) & ~(1<<15); case 3: return mach_read_from_3(value) & 0x3FFFFFUL & ~(1L<<23); case 4: return mach_read_from_4(value) & ~(1L<<31); case 8: return make_longlong(mach_read_from_8(value)) & ~(1LL<<63); } return 0; }
inline unsigned long long int get_uint_value(field_def_t *field, byte *value) { switch (field->fixed_length) { case 1: return mach_read_from_1(value); case 2: return mach_read_from_2(value); case 3: return mach_read_from_3(value) & 0x3FFFFFUL; case 4: return mach_read_from_4(value); case 8: return make_ulonglong(mach_read_from_8(value)); } return 0; }
inline void print_field_value(byte *value, ulint len, field_def_t *field) { switch (field->type) { case FT_INTERNAL: break; case FT_CHAR: case FT_TEXT: print_string((char*)value, len, field); break; case FT_UINT: printf("%llu", get_uint_value(field, value)); break; case FT_INT: printf("%lli", get_int_value(field, value)); break; case FT_FLOAT: printf("%f", mach_float_read(value)); break; case FT_DOUBLE: printf("%lf", mach_double_read(value)); break; case FT_DATETIME: print_datetime(make_longlong(mach_read_from_8(value))); break; case FT_DATE: print_date(mach_read_from_3(value)); break; case FT_TIME: print_time(mach_read_from_3(value)); break; case FT_ENUM: print_enum(mach_read_from_1(value), field); break; case FT_DECIMAL: print_decimal(value, field); break; default: printf("undef(%d)", field->type); } }
byte* trx_undo_rec_get_pars( /*==================*/ /* out: remaining part of undo log record after reading these values */ trx_undo_rec_t* undo_rec, /* in: undo log record */ ulint* type, /* out: undo record type: TRX_UNDO_INSERT_REC, ... */ ulint* cmpl_info, /* out: compiler info, relevant only for update type records */ ibool* updated_extern, /* out: TRUE if we updated an externally stored fild */ dulint* undo_no, /* out: undo log record number */ dulint* table_id) /* out: table id */ { byte* ptr; ulint len; ulint type_cmpl; ptr = undo_rec + 2; type_cmpl = mach_read_from_1(ptr); ptr++; if (type_cmpl & TRX_UNDO_UPD_EXTERN) { *updated_extern = TRUE; type_cmpl -= TRX_UNDO_UPD_EXTERN; } else { *updated_extern = FALSE; } *type = type_cmpl & (TRX_UNDO_CMPL_INFO_MULT - 1); *cmpl_info = type_cmpl / TRX_UNDO_CMPL_INFO_MULT; *undo_no = mach_dulint_read_much_compressed(ptr); len = mach_dulint_get_much_compressed_size(*undo_no); ptr += len; *table_id = mach_dulint_read_much_compressed(ptr); len = mach_dulint_get_much_compressed_size(*table_id); ptr += len; return(ptr); }
/*************************************************************//** Pretty prints a dfield value according to its data type. Also the hex string is printed if a string contains non-printable characters. */ UNIV_INTERN void dfield_print_also_hex( /*==================*/ const dfield_t* dfield) /*!< in: dfield */ { const byte* data; ulint len; ulint prtype; ulint i; ibool print_also_hex; len = dfield_get_len(dfield); data = dfield_get_data(dfield); if (dfield_is_null(dfield)) { fputs("NULL", stderr); return; } prtype = dtype_get_prtype(dfield_get_type(dfield)); switch (dtype_get_mtype(dfield_get_type(dfield))) { dulint id; case DATA_INT: switch (len) { ulint val; case 1: val = mach_read_from_1(data); if (!(prtype & DATA_UNSIGNED)) { val &= ~0x80; fprintf(stderr, "%ld", (long) val); } else { fprintf(stderr, "%lu", (ulong) val); } break; case 2: val = mach_read_from_2(data); if (!(prtype & DATA_UNSIGNED)) { val &= ~0x8000; fprintf(stderr, "%ld", (long) val); } else { fprintf(stderr, "%lu", (ulong) val); } break; case 3: val = mach_read_from_3(data); if (!(prtype & DATA_UNSIGNED)) { val &= ~0x800000; fprintf(stderr, "%ld", (long) val); } else { fprintf(stderr, "%lu", (ulong) val); } break; case 4: val = mach_read_from_4(data); if (!(prtype & DATA_UNSIGNED)) { val &= ~0x80000000; fprintf(stderr, "%ld", (long) val); } else { fprintf(stderr, "%lu", (ulong) val); } break; case 6: id = mach_read_from_6(data); fprintf(stderr, "{%lu %lu}", ut_dulint_get_high(id), ut_dulint_get_low(id)); break; case 7: id = mach_read_from_7(data); fprintf(stderr, "{%lu %lu}", ut_dulint_get_high(id), ut_dulint_get_low(id)); break; case 8: id = mach_read_from_8(data); fprintf(stderr, "{%lu %lu}", ut_dulint_get_high(id), ut_dulint_get_low(id)); break; default: goto print_hex; } break; case DATA_SYS: switch (prtype & DATA_SYS_PRTYPE_MASK) { case DATA_TRX_ID: id = mach_read_from_6(data); fprintf(stderr, "trx_id " TRX_ID_FMT, TRX_ID_PREP_PRINTF(id)); break; case DATA_ROLL_PTR: id = mach_read_from_7(data); fprintf(stderr, "roll_ptr {%lu %lu}", ut_dulint_get_high(id), ut_dulint_get_low(id)); break; case DATA_ROW_ID: id = mach_read_from_6(data); fprintf(stderr, "row_id {%lu %lu}", ut_dulint_get_high(id), ut_dulint_get_low(id)); break; default: id = mach_dulint_read_compressed(data); fprintf(stderr, "mix_id {%lu %lu}", ut_dulint_get_high(id), ut_dulint_get_low(id)); } break; case DATA_CHAR: case DATA_VARCHAR: print_also_hex = FALSE; for (i = 0; i < len; i++) { int c = *data++; if (!isprint(c)) { print_also_hex = TRUE; fprintf(stderr, "\\x%02x", (unsigned char) c); } else { putc(c, stderr); } } if (dfield_is_ext(dfield)) { fputs("(external)", stderr); } if (!print_also_hex) { break; } data = dfield_get_data(dfield); /* fall through */ case DATA_BINARY: default: print_hex: fputs(" Hex: ",stderr); for (i = 0; i < len; i++) { fprintf(stderr, "%02lx", (ulint) *data++); } if (dfield_is_ext(dfield)) { fputs("(external)", stderr); } } }
byte* row_upd_index_parse( /*================*/ /* out: log data end or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ mem_heap_t* heap, /* in: memory heap where update vector is built */ upd_t** update_out)/* out: update vector */ { upd_t* update; upd_field_t* upd_field; dfield_t* new_val; ulint len; ulint n_fields; byte* buf; ulint info_bits; ulint i; if (end_ptr < ptr + 1) { return(NULL); } info_bits = mach_read_from_1(ptr); ptr++; ptr = mach_parse_compressed(ptr, end_ptr, &n_fields); if (ptr == NULL) { return(NULL); } update = upd_create(n_fields, heap); update->info_bits = info_bits; for (i = 0; i < n_fields; i++) { upd_field = upd_get_nth_field(update, i); new_val = &(upd_field->new_val); ptr = mach_parse_compressed(ptr, end_ptr, &(upd_field->field_no)); if (ptr == NULL) { return(NULL); } ptr = mach_parse_compressed(ptr, end_ptr, &len); if (ptr == NULL) { return(NULL); } new_val->len = len; if (len != UNIV_SQL_NULL) { if (end_ptr < ptr + len) { return(NULL); } else { buf = mem_heap_alloc(heap, len); ut_memcpy(buf, ptr, len); ptr += len; new_val->data = buf; } } } *update_out = update; return(ptr); }