MDEV-19385: Inconsistent definition of dtuple_get_nth_v_field()

The accessor dtuple_get_nth_v_field() was defined differently between
debug and release builds in MySQL 5.7.8 in
mysql/mysql-server@c47e1751b7
and a debug assertion to document or enforce the questionable assumption
tuple->v_fields == &tuple->fields[tuple->n_fields] was missing.

This was apparently no problem until MDEV-11369 introduced instant
ADD COLUMN to MariaDB Server 10.3. With that work present, in one
test case, trx_undo_report_insert_virtual() could in release builds
fetch the wrong value for a virtual column.

We replace many of the dtuple_t accessors with const-preserving
inline functions, and fix missing or misleadingly applied const
qualifiers accordingly.
This commit is contained in:
Marko Mäkelä 2019-05-03 16:47:07 +03:00
parent 3db94d2403
commit ce195987c3
21 changed files with 168 additions and 358 deletions

View File

@ -37,7 +37,7 @@ Created 5/30/1994 Heikki Tuuri
/** Dummy variable to catch access to uninitialized fields. In the /** Dummy variable to catch access to uninitialized fields. In the
debug version, dtuple_create() will make all fields of dtuple_t point debug version, dtuple_create() will make all fields of dtuple_t point
to data_error. */ to data_error. */
byte data_error; ut_d(byte data_error);
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/** Compare two data tuples. /** Compare two data tuples.
@ -416,7 +416,7 @@ dfield_print_also_hex(
break; break;
} }
data = static_cast<byte*>(dfield_get_data(dfield)); data = static_cast<const byte*>(dfield_get_data(dfield));
/* fall through */ /* fall through */
case DATA_BINARY: case DATA_BINARY:

View File

@ -3366,12 +3366,11 @@ fts_fetch_doc_from_tuple(
const dict_field_t* ifield; const dict_field_t* ifield;
const dict_col_t* col; const dict_col_t* col;
ulint pos; ulint pos;
dfield_t* field;
ifield = dict_index_get_nth_field(index, i); ifield = dict_index_get_nth_field(index, i);
col = dict_field_get_col(ifield); col = dict_field_get_col(ifield);
pos = dict_col_get_no(col); pos = dict_col_get_no(col);
field = dtuple_get_nth_field(tuple, pos); const dfield_t* field = dtuple_get_nth_field(tuple, pos);
if (!get_doc->index_cache->charset) { if (!get_doc->index_cache->charset) {
get_doc->index_cache->charset = fts_get_charset( get_doc->index_cache->charset = fts_get_charset(

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -68,9 +69,9 @@ static
int int
rtree_add_point_to_mbr( rtree_add_point_to_mbr(
/*===================*/ /*===================*/
uchar** wkb, /*!< in: pointer to wkb, const uchar** wkb, /*!< in: pointer to wkb,
where point is stored */ where point is stored */
uchar* end, /*!< in: end of wkb. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ uint n_dims, /*!< in: dimensions. */
uchar byte_order, /*!< in: byte order. */ uchar byte_order, /*!< in: byte order. */
double* mbr) /*!< in/out: mbr, which double* mbr) /*!< in/out: mbr, which
@ -108,9 +109,9 @@ static
int int
rtree_get_point_mbr( rtree_get_point_mbr(
/*================*/ /*================*/
uchar** wkb, /*!< in: pointer to wkb, const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */ where point is stored. */
uchar* end, /*!< in: end of wkb. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ uint n_dims, /*!< in: dimensions. */
uchar byte_order, /*!< in: byte order. */ uchar byte_order, /*!< in: byte order. */
double* mbr) /*!< in/out: mbr, double* mbr) /*!< in/out: mbr,
@ -127,9 +128,9 @@ static
int int
rtree_get_linestring_mbr( rtree_get_linestring_mbr(
/*=====================*/ /*=====================*/
uchar** wkb, /*!< in: pointer to wkb, const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */ where point is stored. */
uchar* end, /*!< in: end of wkb. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ uint n_dims, /*!< in: dimensions. */
uchar byte_order, /*!< in: byte order. */ uchar byte_order, /*!< in: byte order. */
double* mbr) /*!< in/out: mbr, double* mbr) /*!< in/out: mbr,
@ -158,9 +159,9 @@ static
int int
rtree_get_polygon_mbr( rtree_get_polygon_mbr(
/*==================*/ /*==================*/
uchar** wkb, /*!< in: pointer to wkb, const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */ where point is stored. */
uchar* end, /*!< in: end of wkb. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ uint n_dims, /*!< in: dimensions. */
uchar byte_order, /*!< in: byte order. */ uchar byte_order, /*!< in: byte order. */
double* mbr) /*!< in/out: mbr, double* mbr) /*!< in/out: mbr,
@ -195,9 +196,9 @@ static
int int
rtree_get_geometry_mbr( rtree_get_geometry_mbr(
/*===================*/ /*===================*/
uchar** wkb, /*!< in: pointer to wkb, const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */ where point is stored. */
uchar* end, /*!< in: end of wkb. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ uint n_dims, /*!< in: dimensions. */
double* mbr, /*!< in/out: mbr. */ double* mbr, /*!< in/out: mbr. */
int top) /*!< in: if it is the top, int top) /*!< in: if it is the top,
@ -297,7 +298,7 @@ stored in "well-known binary representation" (wkb) format.
int int
rtree_mbr_from_wkb( rtree_mbr_from_wkb(
/*===============*/ /*===============*/
uchar* wkb, /*!< in: wkb */ const uchar* wkb, /*!< in: wkb */
uint size, /*!< in: size of wkb. */ uint size, /*!< in: size of wkb. */
uint n_dims, /*!< in: dimensions. */ uint n_dims, /*!< in: dimensions. */
double* mbr) /*!< in/out: mbr, which must double* mbr) /*!< in/out: mbr, which must

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -64,7 +65,7 @@ rtr_page_split_initialize_nodes(
page_t* page; page_t* page;
ulint n_uniq; ulint n_uniq;
ulint len; ulint len;
byte* source_cur; const byte* source_cur;
block = btr_cur_get_block(cursor); block = btr_cur_get_block(cursor);
page = buf_block_get_frame(block); page = buf_block_get_frame(block);
@ -104,7 +105,7 @@ rtr_page_split_initialize_nodes(
} }
/* Put the insert key to node list */ /* Put the insert key to node list */
source_cur = static_cast<byte*>(dfield_get_data( source_cur = static_cast<const byte*>(dfield_get_data(
dtuple_get_nth_field(tuple, 0))); dtuple_get_nth_field(tuple, 0)));
cur->coords = reserve_coords(buf_pos, SPDIMS); cur->coords = reserve_coords(buf_pos, SPDIMS);
rec = (byte*) mem_heap_alloc( rec = (byte*) mem_heap_alloc(
@ -1874,11 +1875,11 @@ rtr_estimate_n_rows_in_range(
ulint dtuple_f_len MY_ATTRIBUTE((unused)); ulint dtuple_f_len MY_ATTRIBUTE((unused));
rtr_mbr_t range_mbr; rtr_mbr_t range_mbr;
double range_area; double range_area;
byte* range_mbr_ptr;
dtuple_field = dtuple_get_nth_field(tuple, 0); dtuple_field = dtuple_get_nth_field(tuple, 0);
dtuple_f_len = dfield_get_len(dtuple_field); dtuple_f_len = dfield_get_len(dtuple_field);
range_mbr_ptr = reinterpret_cast<byte*>(dfield_get_data(dtuple_field)); const byte* range_mbr_ptr = static_cast<const byte*>(
dfield_get_data(dtuple_field));
ut_ad(dtuple_f_len >= DATA_MBR_LEN); ut_ad(dtuple_f_len >= DATA_MBR_LEN);
rtr_read_mbr(range_mbr_ptr, &range_mbr); rtr_read_mbr(range_mbr_ptr, &range_mbr);

View File

@ -1631,15 +1631,13 @@ rtr_get_mbr_from_tuple(
{ {
const dfield_t* dtuple_field; const dfield_t* dtuple_field;
ulint dtuple_f_len; ulint dtuple_f_len;
byte* data;
dtuple_field = dtuple_get_nth_field(dtuple, 0); dtuple_field = dtuple_get_nth_field(dtuple, 0);
dtuple_f_len = dfield_get_len(dtuple_field); dtuple_f_len = dfield_get_len(dtuple_field);
ut_a(dtuple_f_len >= 4 * sizeof(double)); ut_a(dtuple_f_len >= 4 * sizeof(double));
data = static_cast<byte*>(dfield_get_data(dtuple_field)); rtr_read_mbr(static_cast<const byte*>(dfield_get_data(dtuple_field)),
mbr);
rtr_read_mbr(data, mbr);
} }
/****************************************************************//** /****************************************************************//**

View File

@ -21784,7 +21784,7 @@ void innobase_free_row_for_vcol(VCOL_STORAGE *storage)
to store the value in passed in "my_rec" */ to store the value in passed in "my_rec" */
dfield_t* dfield_t*
innobase_get_computed_value( innobase_get_computed_value(
const dtuple_t* row, dtuple_t* row,
const dict_v_col_t* col, const dict_v_col_t* col,
const dict_index_t* index, const dict_index_t* index,
mem_heap_t** local_heap, mem_heap_t** local_heap,

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation. Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -31,6 +31,7 @@ Created 5/30/1994 Heikki Tuuri
#include "data0type.h" #include "data0type.h"
#include "mem0mem.h" #include "mem0mem.h"
#include "dict0types.h" #include "dict0types.h"
#include "btr0types.h"
#include <ostream> #include <ostream>
@ -39,29 +40,11 @@ index record which needs external storage of data fields */
struct big_rec_t; struct big_rec_t;
struct upd_t; struct upd_t;
#ifdef UNIV_DEBUG /** Dummy variable to catch access to uninitialized fields. In the
/*********************************************************************//** debug version, dtuple_create() will make all fields of dtuple_t point
Gets pointer to the type struct of SQL data field. to data_error. */
@return pointer to the type struct */ ut_d(extern byte data_error);
UNIV_INLINE
dtype_t*
dfield_get_type(
/*============*/
const dfield_t* field) /*!< in: SQL data field */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Gets pointer to the data in a field.
@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
/*============*/
const dfield_t* field) /*!< in: field */
MY_ATTRIBUTE((nonnull, warn_unused_result));
#else /* UNIV_DEBUG */
# define dfield_get_type(field) (&(field)->type)
# define dfield_get_data(field) ((field)->data)
#endif /* UNIV_DEBUG */
/*********************************************************************//** /*********************************************************************//**
Sets the type struct of SQL data field. */ Sets the type struct of SQL data field. */
UNIV_INLINE UNIV_INLINE
@ -72,15 +55,6 @@ dfield_set_type(
const dtype_t* type); /*!< in: pointer to data type struct */ const dtype_t* type); /*!< in: pointer to data type struct */
/*********************************************************************//** /*********************************************************************//**
Gets length of field data.
@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
/*===========*/
const dfield_t* field) /*!< in: field */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Sets length in a field. */ Sets length in a field. */
UNIV_INLINE UNIV_INLINE
void void
@ -89,32 +63,6 @@ dfield_set_len(
dfield_t* field, /*!< in: field */ dfield_t* field, /*!< in: field */
ulint len) /*!< in: length or UNIV_SQL_NULL */ ulint len) /*!< in: length or UNIV_SQL_NULL */
MY_ATTRIBUTE((nonnull)); MY_ATTRIBUTE((nonnull));
/*********************************************************************//**
Determines if a field is SQL NULL
@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
/*===========*/
const dfield_t* field) /*!< in: field */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Determines if a field is externally stored
@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
/*==========*/
const dfield_t* field) /*!< in: field */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Sets the "external storage" flag */
UNIV_INLINE
void
dfield_set_ext(
/*===========*/
dfield_t* field) /*!< in/out: field */
MY_ATTRIBUTE((nonnull));
/** Gets spatial status for "external storage" /** Gets spatial status for "external storage"
@param[in,out] field field */ @param[in,out] field field */
@ -221,46 +169,7 @@ dfield_data_is_binary_equal(
ulint len, /*!< in: data length or UNIV_SQL_NULL */ ulint len, /*!< in: data length or UNIV_SQL_NULL */
const byte* data) /*!< in: data */ const byte* data) /*!< in: data */
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Gets number of fields in a data tuple.
@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
const dtuple_t* tuple) /*!< in: tuple */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Gets number of virtual fields in a data tuple.
@param[in] tuple dtuple to check
@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_v_fields(
const dtuple_t* tuple);
#ifdef UNIV_DEBUG
/** Gets nth field of a tuple.
@param[in] tuple tuple
@param[in] n index of field
@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
const dtuple_t* tuple,
ulint n);
/** Gets nth virtual field of a tuple.
@param[in] tuple tuple
@oaran[in] n the nth field to get
@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_v_field(
const dtuple_t* tuple,
ulint n);
#else /* UNIV_DEBUG */
# define dtuple_get_nth_field(tuple, n) ((tuple)->fields + (n))
# define dtuple_get_nth_v_field(tuple, n) ((tuple)->fields + (tuple)->n_fields + (n))
#endif /* UNIV_DEBUG */
/*********************************************************************//** /*********************************************************************//**
Gets info bits in a data tuple. Gets info bits in a data tuple.
@return info bits */ @return info bits */
@ -338,19 +247,12 @@ dtuple_create(
/** Initialize the virtual field data in a dtuple_t /** Initialize the virtual field data in a dtuple_t
@param[in,out] vrow dtuple contains the virtual fields */ @param[in,out] vrow dtuple contains the virtual fields */
UNIV_INLINE UNIV_INLINE void dtuple_init_v_fld(dtuple_t* vrow);
void
dtuple_init_v_fld(
const dtuple_t* vrow);
/** Duplicate the virtual field data in a dtuple_t /** Duplicate the virtual field data in a dtuple_t
@param[in,out] vrow dtuple contains the virtual fields @param[in,out] vrow dtuple contains the virtual fields
@param[in] heap heap memory to use */ @param[in] heap heap memory to use */
UNIV_INLINE UNIV_INLINE void dtuple_dup_v_fld(dtuple_t* vrow, mem_heap_t* heap);
void
dtuple_dup_v_fld(
const dtuple_t* vrow,
mem_heap_t* heap);
/** Creates a data tuple with possible virtual columns to a memory heap. /** Creates a data tuple with possible virtual columns to a memory heap.
@param[in] heap memory heap where the tuple is created @param[in] heap memory heap where the tuple is created
@ -619,6 +521,69 @@ struct dtuple_t {
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
}; };
inline ulint dtuple_get_n_fields(const dtuple_t* tuple)
{ return tuple->n_fields; }
inline dtype_t* dfield_get_type(dfield_t* field) { return &field->type; }
inline const dtype_t* dfield_get_type(const dfield_t* field)
{ return &field->type; }
inline void* dfield_get_data(dfield_t* field)
{
ut_ad(field->len == UNIV_SQL_NULL || field->data != &data_error);
return field->data;
}
inline const void* dfield_get_data(const dfield_t* field)
{
ut_ad(field->len == UNIV_SQL_NULL || field->data != &data_error);
return field->data;
}
inline ulint dfield_get_len(const dfield_t* field) { return field->len; }
inline bool dfield_is_null(const dfield_t* field)
{ return field->len == UNIV_SQL_NULL; }
/** @return whether a column is to be stored off-page */
inline bool dfield_is_ext(const dfield_t* field)
{
ut_ad(!field->ext || field->len >= BTR_EXTERN_FIELD_REF_SIZE);
return static_cast<bool>(field->ext);
}
/** Set the "external storage" flag */
inline void dfield_set_ext(dfield_t* field) { field->ext = 1; }
/** Gets number of virtual fields in a data tuple.
@param[in] tuple dtuple to check
@return number of fields */
inline ulint
dtuple_get_n_v_fields(const dtuple_t* tuple) { return tuple->n_v_fields; }
inline const dfield_t* dtuple_get_nth_field(const dtuple_t* tuple, ulint n)
{
ut_ad(n < tuple->n_fields);
return &tuple->fields[n];
}
inline dfield_t* dtuple_get_nth_field(dtuple_t* tuple, ulint n)
{
ut_ad(n < tuple->n_fields);
return &tuple->fields[n];
}
/** Get a virtual column in a table row or an extended clustered index record.
@param[in] tuple tuple
@oaran[in] n the nth virtual field to get
@return nth virtual field */
inline const dfield_t* dtuple_get_nth_v_field(const dtuple_t* tuple, ulint n)
{
ut_ad(n < tuple->n_v_fields);
return &tuple->v_fields[n];
}
/** Get a virtual column in a table row or an extended clustered index record.
@param[in] tuple tuple
@oaran[in] n the nth virtual field to get
@return nth virtual field */
inline dfield_t* dtuple_get_nth_v_field(dtuple_t* tuple, ulint n)
{
ut_ad(n < tuple->n_v_fields);
return &tuple->v_fields[n];
}
/** A slot for a field in a big rec vector */ /** A slot for a field in a big rec vector */
struct big_rec_field_t { struct big_rec_field_t {

View File

@ -24,28 +24,7 @@ SQL data field and tuple
Created 5/30/1994 Heikki Tuuri Created 5/30/1994 Heikki Tuuri
*************************************************************************/ *************************************************************************/
#include "mem0mem.h"
#include "ut0rnd.h" #include "ut0rnd.h"
#include "btr0types.h"
#ifdef UNIV_DEBUG
/** Dummy variable to catch access to uninitialized fields. In the
debug version, dtuple_create() will make all fields of dtuple_t point
to data_error. */
extern byte data_error;
/*********************************************************************//**
Gets pointer to the type struct of SQL data field.
@return pointer to the type struct */
UNIV_INLINE
dtype_t*
dfield_get_type(
/*============*/
const dfield_t* field) /*!< in: SQL data field */
{
return((dtype_t*) &(field->type));
}
#endif /* UNIV_DEBUG */
/*********************************************************************//** /*********************************************************************//**
Sets the type struct of SQL data field. */ Sets the type struct of SQL data field. */
@ -62,38 +41,6 @@ dfield_set_type(
field->type = *type; field->type = *type;
} }
#ifdef UNIV_DEBUG
/*********************************************************************//**
Gets pointer to the data in a field.
@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
/*============*/
const dfield_t* field) /*!< in: field */
{
ut_ad((field->len == UNIV_SQL_NULL)
|| (field->data != &data_error));
return((void*) field->data);
}
#endif /* UNIV_DEBUG */
/*********************************************************************//**
Gets length of field data.
@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
/*===========*/
const dfield_t* field) /*!< in: field */
{
ut_ad((field->len == UNIV_SQL_NULL)
|| (field->data != &data_error));
return(field->len);
}
/*********************************************************************//** /*********************************************************************//**
Sets length in a field. */ Sets length in a field. */
UNIV_INLINE UNIV_INLINE
@ -111,42 +58,6 @@ dfield_set_len(
field->len = static_cast<unsigned int>(len); field->len = static_cast<unsigned int>(len);
} }
/*********************************************************************//**
Determines if a field is SQL NULL
@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
/*===========*/
const dfield_t* field) /*!< in: field */
{
return(field->len == UNIV_SQL_NULL);
}
/*********************************************************************//**
Determines if a field is externally stored
@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
/*==========*/
const dfield_t* field) /*!< in: field */
{
ut_ad(!field->ext || field->len >= BTR_EXTERN_FIELD_REF_SIZE);
return(field->ext);
}
/*********************************************************************//**
Sets the "external storage" flag */
UNIV_INLINE
void
dfield_set_ext(
/*===========*/
dfield_t* field) /*!< in/out: field */
{
field->ext = 1;
}
/** Gets spatial status for "external storage" /** Gets spatial status for "external storage"
@param[in,out] field field */ @param[in,out] field field */
UNIV_INLINE UNIV_INLINE
@ -366,63 +277,6 @@ dtuple_set_n_fields_cmp(
tuple->n_fields_cmp = n_fields_cmp; tuple->n_fields_cmp = n_fields_cmp;
} }
/*********************************************************************//**
Gets number of fields in a data tuple.
@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
const dtuple_t* tuple) /*!< in: tuple */
{
return(tuple->n_fields);
}
/** Gets the number of virtual fields in a data tuple.
@param[in] tuple dtuple to check
@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_v_fields(
const dtuple_t* tuple)
{
ut_ad(tuple);
return(tuple->n_v_fields);
}
#ifdef UNIV_DEBUG
/** Gets nth field of a tuple.
@param[in] tuple tuple
@param[in] n index of field
@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
const dtuple_t* tuple,
ulint n)
{
ut_ad(tuple);
ut_ad(n < tuple->n_fields);
return((dfield_t*) tuple->fields + n);
}
/** Gets nth virtual field of a tuple.
@param[in] tuple tuple
@oaran[in] n the nth field to get
@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_v_field(
const dtuple_t* tuple,
ulint n)
{
ut_ad(tuple);
ut_ad(n < tuple->n_v_fields);
return(static_cast<dfield_t*>(tuple->v_fields + n));
}
#endif /* UNIV_DEBUG */
/** Creates a data tuple from an already allocated chunk of memory. /** Creates a data tuple from an already allocated chunk of memory.
The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields). The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields).
The default value for number of fields used in record comparisons The default value for number of fields used in record comparisons
@ -487,12 +341,10 @@ dtuple_create_from_mem(
/** Duplicate the virtual field data in a dtuple_t /** Duplicate the virtual field data in a dtuple_t
@param[in,out] vrow dtuple contains the virtual fields @param[in,out] vrow dtuple contains the virtual fields
@param[in] heap heap memory to use */ @param[in,out] heap heap memory to use */
UNIV_INLINE UNIV_INLINE
void void
dtuple_dup_v_fld( dtuple_dup_v_fld(dtuple_t* vrow, mem_heap_t* heap)
const dtuple_t* vrow,
mem_heap_t* heap)
{ {
for (ulint i = 0; i < vrow->n_v_fields; i++) { for (ulint i = 0; i < vrow->n_v_fields; i++) {
dfield_t* dfield = dtuple_get_nth_v_field(vrow, i); dfield_t* dfield = dtuple_get_nth_v_field(vrow, i);
@ -504,8 +356,7 @@ dtuple_dup_v_fld(
@param[in,out] vrow dtuple contains the virtual fields */ @param[in,out] vrow dtuple contains the virtual fields */
UNIV_INLINE UNIV_INLINE
void void
dtuple_init_v_fld( dtuple_init_v_fld(dtuple_t* vrow)
const dtuple_t* vrow)
{ {
for (ulint i = 0; i < vrow->n_v_fields; i++) { for (ulint i = 0; i < vrow->n_v_fields; i++) {
dfield_t* dfield = dtuple_get_nth_v_field(vrow, i); dfield_t* dfield = dtuple_get_nth_v_field(vrow, i);

View File

@ -1,5 +1,6 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -73,7 +74,7 @@ stored in "well-known binary representation" (wkb) format.
int int
rtree_mbr_from_wkb( rtree_mbr_from_wkb(
/*===============*/ /*===============*/
uchar* wkb, /*!< in: pointer to wkb. */ const uchar* wkb, /*!< in: pointer to wkb. */
uint size, /*!< in: size of wkb. */ uint size, /*!< in: size of wkb. */
uint n_dims, /*!< in: dimensions. */ uint n_dims, /*!< in: dimensions. */
double* mbr); /*!< in/out: mbr. */ double* mbr); /*!< in/out: mbr. */

View File

@ -127,10 +127,10 @@ cmp_dfield_dfield_like_prefix(
if (CHARSET_INFO* cs = get_charset(cs_num, MYF(MY_WME))) { if (CHARSET_INFO* cs = get_charset(cs_num, MYF(MY_WME))) {
return(cs->coll->strnncoll( return(cs->coll->strnncoll(
cs, cs,
static_cast<uchar*>( static_cast<const uchar*>(
dfield_get_data(dfield1)), dfield_get_data(dfield1)),
dfield_get_len(dfield1), dfield_get_len(dfield1),
static_cast<uchar*>( static_cast<const uchar*>(
dfield_get_data(dfield2)), dfield_get_data(dfield2)),
dfield_get_len(dfield2), dfield_get_len(dfield2),
1)); 1));

View File

@ -858,7 +858,7 @@ void innobase_free_row_for_vcol(VCOL_STORAGE *storage);
@return the field filled with computed value */ @return the field filled with computed value */
dfield_t* dfield_t*
innobase_get_computed_value( innobase_get_computed_value(
const dtuple_t* row, dtuple_t* row,
const dict_v_col_t* col, const dict_v_col_t* col,
const dict_index_t* index, const dict_index_t* index,
mem_heap_t** local_heap, mem_heap_t** local_heap,

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -124,7 +124,7 @@ row_vers_build_for_consistent_read(
if the history is missing or the record if the history is missing or the record
does not exist in the view, that is, does not exist in the view, that is,
it was freshly inserted afterwards */ it was freshly inserted afterwards */
const dtuple_t**vrow); /*!< out: reports virtual column info if any */ dtuple_t** vrow); /*!< out: reports virtual column info if any */
/*****************************************************************//** /*****************************************************************//**
Constructs the last committed version of a clustered index record, Constructs the last committed version of a clustered index record,
@ -149,7 +149,7 @@ row_vers_build_for_semi_consistent_read(
const rec_t** old_vers,/*!< out: rec, old version, or NULL if the const rec_t** old_vers,/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is, record does not exist in the view, that is,
it was freshly inserted afterwards */ it was freshly inserted afterwards */
const dtuple_t**vrow); /*!< out: holds virtual column info if any dtuple_t** vrow); /*!< out: holds virtual column info if any
is updated in the view */ is updated in the view */
#endif #endif

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation. Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -250,7 +250,7 @@ trx_undo_prev_version_build(
dtuple if it is not yet created. This heap dtuple if it is not yet created. This heap
diffs from "heap" above in that it could be diffs from "heap" above in that it could be
prebuilt->old_vers_heap for selection */ prebuilt->old_vers_heap for selection */
const dtuple_t**vrow, /*!< out: virtual column info, if any */ dtuple_t** vrow, /*!< out: virtual column info, if any */
ulint v_status); ulint v_status);
/*!< in: status determine if it is going /*!< in: status determine if it is going
into this function by purge thread or not. into this function by purge thread or not.
@ -299,7 +299,7 @@ void
trx_undo_read_v_cols( trx_undo_read_v_cols(
const dict_table_t* table, const dict_table_t* table,
const byte* ptr, const byte* ptr,
const dtuple_t* row, dtuple_t* row,
bool in_purge); bool in_purge);
/** Read virtual column index from undo log if the undo log contains such /** Read virtual column index from undo log if the undo log contains such

View File

@ -838,9 +838,7 @@ rec_get_converted_size_comp_prefix_low(
col = dict_field_get_col(field); col = dict_field_get_col(field);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
dtype_t* type; const dtype_t* type = dfield_get_type(&fields[i]);
type = dfield_get_type(&fields[i]);
if (dict_index_is_spatial(index)) { if (dict_index_is_spatial(index)) {
if (DATA_GEOMETRY_MTYPE(col->mtype) && i == 0) { if (DATA_GEOMETRY_MTYPE(col->mtype) && i == 0) {
ut_ad(type->prtype & DATA_GIS_MBR); ut_ad(type->prtype & DATA_GIS_MBR);

View File

@ -3327,14 +3327,14 @@ row_ins_spatial_index_entry_set_mbr_field(
dfield_t* field, /*!< in/out: mbr field */ dfield_t* field, /*!< in/out: mbr field */
const dfield_t* row_field) /*!< in: row field */ const dfield_t* row_field) /*!< in: row field */
{ {
uchar* dptr = NULL;
ulint dlen = 0; ulint dlen = 0;
double mbr[SPDIMS * 2]; double mbr[SPDIMS * 2];
/* This must be a GEOMETRY datatype */ /* This must be a GEOMETRY datatype */
ut_ad(DATA_GEOMETRY_MTYPE(field->type.mtype)); ut_ad(DATA_GEOMETRY_MTYPE(field->type.mtype));
dptr = static_cast<uchar*>(dfield_get_data(row_field)); const byte* dptr = static_cast<const byte*>(
dfield_get_data(row_field));
dlen = dfield_get_len(row_field); dlen = dfield_get_len(row_field);
/* obtain the MBR */ /* obtain the MBR */

View File

@ -453,7 +453,7 @@ row_merge_buf_redundant_convert(
ut_ad(field_len <= len); ut_ad(field_len <= len);
if (row_field->ext) { if (row_field->ext) {
const byte* field_data = static_cast<byte*>( const byte* field_data = static_cast<const byte*>(
dfield_get_data(row_field)); dfield_get_data(row_field));
ulint ext_len; ulint ext_len;
@ -483,7 +483,7 @@ row_merge_buf_redundant_convert(
@param[in] old_table original table @param[in] old_table original table
@param[in] new_table new table @param[in] new_table new table
@param[in,out] psort_info parallel sort info @param[in,out] psort_info parallel sort info
@param[in] row table row @param[in,out] row table row
@param[in] ext cache of externally stored @param[in] ext cache of externally stored
column prefixes, or NULL column prefixes, or NULL
@param[in,out] doc_id Doc ID if we are creating @param[in,out] doc_id Doc ID if we are creating
@ -505,7 +505,7 @@ row_merge_buf_add(
const dict_table_t* old_table, const dict_table_t* old_table,
const dict_table_t* new_table, const dict_table_t* new_table,
fts_psort_t* psort_info, fts_psort_t* psort_info,
const dtuple_t* row, dtuple_t* row,
const row_ext_t* ext, const row_ext_t* ext,
doc_id_t* doc_id, doc_id_t* doc_id,
mem_heap_t* conv_heap, mem_heap_t* conv_heap,
@ -642,7 +642,7 @@ row_merge_buf_add(
row, row,
index->table->fts->doc_col); index->table->fts->doc_col);
*doc_id = (doc_id_t) mach_read_from_8( *doc_id = (doc_id_t) mach_read_from_8(
static_cast<byte*>( static_cast<const byte*>(
dfield_get_data(doc_field))); dfield_get_data(doc_field)));
if (*doc_id == 0) { if (*doc_id == 0) {
@ -1904,7 +1904,7 @@ row_merge_read_clustered_index(
const rec_t* rec; const rec_t* rec;
ulint* offsets; ulint* offsets;
const dtuple_t* row; dtuple_t* row;
row_ext_t* ext; row_ext_t* ext;
page_cur_t* cur = btr_pcur_get_page_cur(&pcur); page_cur_t* cur = btr_pcur_get_page_cur(&pcur);
@ -2154,9 +2154,8 @@ end_of_index:
ut_ad(add_autoinc ut_ad(add_autoinc
< dict_table_get_n_user_cols(new_table)); < dict_table_get_n_user_cols(new_table));
const dfield_t* dfield; dfield_t* dfield = dtuple_get_nth_field(row,
add_autoinc);
dfield = dtuple_get_nth_field(row, add_autoinc);
if (dfield_is_null(dfield)) { if (dfield_is_null(dfield)) {
goto write_buffers; goto write_buffers;
} }

View File

@ -95,7 +95,7 @@ row_build_index_entry_low(
const dict_col_t* col; const dict_col_t* col;
ulint col_no = 0; ulint col_no = 0;
dfield_t* dfield; dfield_t* dfield;
dfield_t* dfield2; const dfield_t* dfield2;
ulint len; ulint len;
if (i >= entry_len) { if (i >= entry_len) {
@ -162,7 +162,7 @@ row_build_index_entry_low(
dfield_set_data(dfield, mbr, mbr_len); dfield_set_data(dfield, mbr, mbr_len);
if (dfield2->data) { if (dfield2->data) {
uchar* dptr = NULL; const uchar* dptr = NULL;
ulint dlen = 0; ulint dlen = 0;
ulint flen = 0; ulint flen = 0;
double tmp_mbr[SPDIMS * 2]; double tmp_mbr[SPDIMS * 2];
@ -170,7 +170,7 @@ row_build_index_entry_low(
if (dfield_is_ext(dfield2)) { if (dfield_is_ext(dfield2)) {
if (flag == ROW_BUILD_FOR_PURGE) { if (flag == ROW_BUILD_FOR_PURGE) {
byte* ptr = NULL; const byte* ptr = NULL;
spatial_status_t spatial_status; spatial_status_t spatial_status;
spatial_status = spatial_status =
@ -179,7 +179,7 @@ row_build_index_entry_low(
switch (spatial_status) { switch (spatial_status) {
case SPATIAL_ONLY: case SPATIAL_ONLY:
ptr = static_cast<byte*>( ptr = static_cast<const byte*>(
dfield_get_data( dfield_get_data(
dfield2)); dfield2));
ut_ad(dfield_get_len(dfield2) ut_ad(dfield_get_len(dfield2)
@ -187,7 +187,7 @@ row_build_index_entry_low(
break; break;
case SPATIAL_MIXED: case SPATIAL_MIXED:
ptr = static_cast<byte*>( ptr = static_cast<const byte*>(
dfield_get_data( dfield_get_data(
dfield2)) dfield2))
+ dfield_get_len( + dfield_get_len(
@ -216,13 +216,13 @@ row_build_index_entry_low(
flen = BTR_EXTERN_FIELD_REF_SIZE; flen = BTR_EXTERN_FIELD_REF_SIZE;
ut_ad(dfield_get_len(dfield2) >= ut_ad(dfield_get_len(dfield2) >=
BTR_EXTERN_FIELD_REF_SIZE); BTR_EXTERN_FIELD_REF_SIZE);
dptr = static_cast<byte*>( dptr = static_cast<const byte*>(
dfield_get_data(dfield2)) dfield_get_data(dfield2))
+ dfield_get_len(dfield2) + dfield_get_len(dfield2)
- BTR_EXTERN_FIELD_REF_SIZE; - BTR_EXTERN_FIELD_REF_SIZE;
} else { } else {
flen = dfield_get_len(dfield2); flen = dfield_get_len(dfield2);
dptr = static_cast<byte*>( dptr = static_cast<const byte*>(
dfield_get_data(dfield2)); dfield_get_data(dfield2));
} }
@ -240,7 +240,7 @@ row_build_index_entry_low(
flen, flen,
temp_heap); temp_heap);
} else { } else {
dptr = static_cast<uchar*>( dptr = static_cast<const uchar*>(
dfield_get_data(dfield2)); dfield_get_data(dfield2));
dlen = dfield_get_len(dfield2); dlen = dfield_get_len(dfield2);

View File

@ -222,7 +222,6 @@ row_sel_sec_rec_is_for_clust_rec(
reconstructed from base column in cluster index */ reconstructed from base column in cluster index */
if (is_virtual) { if (is_virtual) {
const dict_v_col_t* v_col; const dict_v_col_t* v_col;
const dtuple_t* row;
dfield_t* vfield; dfield_t* vfield;
row_ext_t* ext; row_ext_t* ext;
@ -239,7 +238,8 @@ row_sel_sec_rec_is_for_clust_rec(
v_col = reinterpret_cast<const dict_v_col_t*>(col); v_col = reinterpret_cast<const dict_v_col_t*>(col);
row = row_build(ROW_COPY_POINTERS, dtuple_t* row = row_build(
ROW_COPY_POINTERS,
clust_index, clust_rec, clust_index, clust_rec,
clust_offs, clust_offs,
NULL, NULL, NULL, &ext, heap); NULL, NULL, NULL, &ext, heap);
@ -804,7 +804,7 @@ row_sel_build_committed_vers_for_mysql(
record does not exist in the view: record does not exist in the view:
i.e., it was freshly inserted i.e., it was freshly inserted
afterwards */ afterwards */
const dtuple_t**vrow, /*!< out: to be filled with old virtual dtuple_t** vrow, /*!< out: to be filled with old virtual
column version if any */ column version if any */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
@ -3291,7 +3291,7 @@ row_sel_build_prev_vers_for_mysql(
record does not exist in the view: record does not exist in the view:
i.e., it was freshly inserted i.e., it was freshly inserted
afterwards */ afterwards */
const dtuple_t**vrow, /*!< out: dtuple to hold old virtual dtuple_t** vrow, /*!< out: dtuple to hold old virtual
column data */ column data */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
@ -3335,7 +3335,7 @@ row_sel_get_clust_rec_for_mysql(
rec_get_offsets(out_rec, clust_index) */ rec_get_offsets(out_rec, clust_index) */
mem_heap_t** offset_heap,/*!< in/out: memory heap from which mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */ the offsets are allocated */
const dtuple_t**vrow, /*!< out: virtual column to fill */ dtuple_t** vrow, /*!< out: virtual column to fill */
mtr_t* mtr) /*!< in: mtr used to get access to the mtr_t* mtr) /*!< in: mtr used to get access to the
non-clustered record; the same mtr is used to non-clustered record; the same mtr is used to
access the clustered index */ access the clustered index */
@ -4038,7 +4038,7 @@ void
row_sel_fill_vrow( row_sel_fill_vrow(
const rec_t* rec, const rec_t* rec,
dict_index_t* index, dict_index_t* index,
const dtuple_t** vrow, dtuple_t** vrow,
mem_heap_t* heap) mem_heap_t* heap)
{ {
ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint offsets_[REC_OFFS_NORMAL_SIZE];
@ -4230,7 +4230,7 @@ row_search_mvcc(
dict_index_t* clust_index; dict_index_t* clust_index;
que_thr_t* thr; que_thr_t* thr;
const rec_t* rec; const rec_t* rec;
const dtuple_t* vrow = NULL; dtuple_t* vrow = NULL;
const rec_t* result_rec = NULL; const rec_t* result_rec = NULL;
const rec_t* clust_rec; const rec_t* clust_rec;
dberr_t err = DB_SUCCESS; dberr_t err = DB_SUCCESS;

View File

@ -856,7 +856,7 @@ row_upd_index_write_log(
mlog_catenate_string( mlog_catenate_string(
mtr, mtr,
static_cast<byte*>( static_cast<const byte*>(
dfield_get_data(new_val)), dfield_get_data(new_val)),
len); len);
@ -1052,8 +1052,6 @@ row_upd_build_difference_binary(
dberr_t* error) dberr_t* error)
{ {
upd_field_t* upd_field; upd_field_t* upd_field;
dfield_t* dfield;
const byte* data;
ulint len; ulint len;
upd_t* update; upd_t* update;
ulint n_diff; ulint n_diff;
@ -1084,10 +1082,8 @@ row_upd_build_difference_binary(
} }
for (i = 0; i < n_fld; i++) { for (i = 0; i < n_fld; i++) {
const byte* data = rec_get_nth_field(rec, offsets, i, &len);
data = rec_get_nth_field(rec, offsets, i, &len); const dfield_t* dfield = dtuple_get_nth_field(entry, i);
dfield = dtuple_get_nth_field(entry, i);
/* NOTE: we compare the fields as binary strings! /* NOTE: we compare the fields as binary strings!
(No collation) */ (No collation) */
@ -1155,8 +1151,6 @@ row_upd_build_difference_binary(
index->table, NULL, NULL, &ext, heap); index->table, NULL, NULL, &ext, heap);
} }
dfield = dtuple_get_nth_v_field(entry, i);
dfield_t* vfield = innobase_get_computed_value( dfield_t* vfield = innobase_get_computed_value(
update->old_vrow, col, index, update->old_vrow, col, index,
&v_heap, heap, NULL, thd, mysql_table, record, &v_heap, heap, NULL, thd, mysql_table, record,
@ -1167,6 +1161,9 @@ row_upd_build_difference_binary(
return(NULL); return(NULL);
} }
const dfield_t* dfield = dtuple_get_nth_v_field(
entry, i);
if (!dfield_data_is_binary_equal( if (!dfield_data_is_binary_equal(
dfield, vfield->len, dfield, vfield->len,
static_cast<byte*>(vfield->data))) { static_cast<byte*>(vfield->data))) {
@ -1771,7 +1768,7 @@ row_upd_changes_ord_field_binary_func(
double mbr2[SPDIMS * 2]; double mbr2[SPDIMS * 2];
rtr_mbr_t* old_mbr; rtr_mbr_t* old_mbr;
rtr_mbr_t* new_mbr; rtr_mbr_t* new_mbr;
uchar* dptr = NULL; const uchar* dptr = NULL;
ulint flen = 0; ulint flen = 0;
ulint dlen = 0; ulint dlen = 0;
mem_heap_t* temp_heap = NULL; mem_heap_t* temp_heap = NULL;
@ -1792,7 +1789,7 @@ row_upd_changes_ord_field_binary_func(
/* For off-page stored data, we /* For off-page stored data, we
need to read the whole field data. */ need to read the whole field data. */
flen = dfield_get_len(dfield); flen = dfield_get_len(dfield);
dptr = static_cast<byte*>( dptr = static_cast<const byte*>(
dfield_get_data(dfield)); dfield_get_data(dfield));
temp_heap = mem_heap_create(1000); temp_heap = mem_heap_create(1000);
@ -1802,7 +1799,7 @@ row_upd_changes_ord_field_binary_func(
flen, flen,
temp_heap); temp_heap);
} else { } else {
dptr = static_cast<uchar*>(dfield->data); dptr = static_cast<const uchar*>(dfield->data);
dlen = dfield->len; dlen = dfield->len;
} }
@ -1822,13 +1819,13 @@ row_upd_changes_ord_field_binary_func(
flen = BTR_EXTERN_FIELD_REF_SIZE; flen = BTR_EXTERN_FIELD_REF_SIZE;
ut_ad(dfield_get_len(new_field) >= ut_ad(dfield_get_len(new_field) >=
BTR_EXTERN_FIELD_REF_SIZE); BTR_EXTERN_FIELD_REF_SIZE);
dptr = static_cast<byte*>( dptr = static_cast<const byte*>(
dfield_get_data(new_field)) dfield_get_data(new_field))
+ dfield_get_len(new_field) + dfield_get_len(new_field)
- BTR_EXTERN_FIELD_REF_SIZE; - BTR_EXTERN_FIELD_REF_SIZE;
} else { } else {
flen = dfield_get_len(new_field); flen = dfield_get_len(new_field);
dptr = static_cast<byte*>( dptr = static_cast<const byte*>(
dfield_get_data(new_field)); dfield_get_data(new_field));
} }
@ -1842,7 +1839,8 @@ row_upd_changes_ord_field_binary_func(
flen, flen,
temp_heap); temp_heap);
} else { } else {
dptr = static_cast<uchar*>(upd_field->new_val.data); dptr = static_cast<const byte*>(
upd_field->new_val.data);
dlen = upd_field->new_val.len; dlen = upd_field->new_val.len;
} }
rtree_mbr_from_wkb(dptr + GEO_DATA_HEADER_SIZE, rtree_mbr_from_wkb(dptr + GEO_DATA_HEADER_SIZE,
@ -1900,7 +1898,7 @@ row_upd_changes_ord_field_binary_func(
ut_a(dict_index_is_clust(index) ut_a(dict_index_is_clust(index)
|| ind_field->prefix_len <= dfield_len); || ind_field->prefix_len <= dfield_len);
buf = static_cast<byte*>(dfield_get_data(dfield)); buf= static_cast<const byte*>(dfield_get_data(dfield));
copy_dfield: copy_dfield:
ut_a(dfield_len > 0); ut_a(dfield_len > 0);
dfield_copy(&dfield_ext, dfield); dfield_copy(&dfield_ext, dfield);

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation. Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -98,7 +98,7 @@ row_vers_impl_x_locked_low(
mem_heap_t* heap; mem_heap_t* heap;
dtuple_t* ientry = NULL; dtuple_t* ientry = NULL;
mem_heap_t* v_heap = NULL; mem_heap_t* v_heap = NULL;
const dtuple_t* cur_vrow = NULL; dtuple_t* cur_vrow = NULL;
DBUG_ENTER("row_vers_impl_x_locked_low"); DBUG_ENTER("row_vers_impl_x_locked_low");
@ -165,7 +165,7 @@ row_vers_impl_x_locked_low(
ulint vers_del; ulint vers_del;
trx_id_t prev_trx_id; trx_id_t prev_trx_id;
mem_heap_t* old_heap = heap; mem_heap_t* old_heap = heap;
const dtuple_t* vrow = NULL; dtuple_t* vrow = NULL;
/* We keep the semaphore in mtr on the clust_rec page, so /* We keep the semaphore in mtr on the clust_rec page, so
that no other transaction can update it and get an that no other transaction can update it and get an
@ -519,7 +519,7 @@ row_vers_build_cur_vrow_low(
roll_ptr_t roll_ptr, roll_ptr_t roll_ptr,
trx_id_t trx_id, trx_id_t trx_id,
mem_heap_t* v_heap, mem_heap_t* v_heap,
const dtuple_t** vrow, dtuple_t** vrow,
mtr_t* mtr) mtr_t* mtr)
{ {
const rec_t* version; const rec_t* version;
@ -636,7 +636,7 @@ row_vers_vc_matches_cluster(
roll_ptr_t roll_ptr, roll_ptr_t roll_ptr,
trx_id_t trx_id, trx_id_t trx_id,
mem_heap_t* v_heap, mem_heap_t* v_heap,
const dtuple_t**vrow, dtuple_t** vrow,
mtr_t* mtr) mtr_t* mtr)
{ {
const rec_t* version; const rec_t* version;
@ -801,7 +801,7 @@ func_exit:
@param[in,out] vcol_info virtual column information for purge thread @param[in,out] vcol_info virtual column information for purge thread
@return dtuple contains virtual column data */ @return dtuple contains virtual column data */
static static
const dtuple_t* dtuple_t*
row_vers_build_cur_vrow( row_vers_build_cur_vrow(
bool in_purge, bool in_purge,
const rec_t* rec, const rec_t* rec,
@ -816,7 +816,7 @@ row_vers_build_cur_vrow(
mtr_t* mtr, mtr_t* mtr,
purge_vcol_info_t* vcol_info) purge_vcol_info_t* vcol_info)
{ {
const dtuple_t* cur_vrow = NULL; dtuple_t* cur_vrow = NULL;
roll_ptr_t t_roll_ptr = row_get_rec_roll_ptr( roll_ptr_t t_roll_ptr = row_get_rec_roll_ptr(
rec, clust_index, *clust_offsets); rec, clust_index, *clust_offsets);
@ -897,9 +897,9 @@ row_vers_old_has_index_entry(
dtuple_t* row; dtuple_t* row;
const dtuple_t* entry; const dtuple_t* entry;
ulint comp; ulint comp;
const dtuple_t* vrow = NULL; dtuple_t* vrow = NULL;
mem_heap_t* v_heap = NULL; mem_heap_t* v_heap = NULL;
const dtuple_t* cur_vrow = NULL; dtuple_t* cur_vrow = NULL;
ut_ad(mtr_memo_contains_page_flagged(mtr, rec, MTR_MEMO_PAGE_X_FIX ut_ad(mtr_memo_contains_page_flagged(mtr, rec, MTR_MEMO_PAGE_X_FIX
| MTR_MEMO_PAGE_S_FIX)); | MTR_MEMO_PAGE_S_FIX));
@ -1162,7 +1162,7 @@ row_vers_build_for_consistent_read(
if the history is missing or the record if the history is missing or the record
does not exist in the view, that is, does not exist in the view, that is,
it was freshly inserted afterwards */ it was freshly inserted afterwards */
const dtuple_t**vrow) /*!< out: virtual row */ dtuple_t** vrow) /*!< out: virtual row */
{ {
const rec_t* version; const rec_t* version;
rec_t* prev_version; rec_t* prev_version;
@ -1275,7 +1275,7 @@ row_vers_build_for_semi_consistent_read(
const rec_t** old_vers,/*!< out: rec, old version, or NULL if the const rec_t** old_vers,/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is, record does not exist in the view, that is,
it was freshly inserted afterwards */ it was freshly inserted afterwards */
const dtuple_t** vrow) /*!< out: virtual row, old version, or NULL dtuple_t** vrow) /*!< out: virtual row, old version, or NULL
if it is not updated in the view */ if it is not updated in the view */
{ {
const rec_t* version; const rec_t* version;

View File

@ -388,8 +388,6 @@ trx_undo_report_insert_virtual(
for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(table); for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(table);
col_no++) { col_no++) {
dfield_t* vfield = NULL;
const dict_v_col_t* col const dict_v_col_t* col
= dict_table_get_nth_v_col(table, col_no); = dict_table_get_nth_v_col(table, col_no);
@ -412,7 +410,8 @@ trx_undo_report_insert_virtual(
return(false); return(false);
} }
vfield = dtuple_get_nth_v_field(row, col->v_pos); const dfield_t* vfield = dtuple_get_nth_v_field(
row, col->v_pos);
ulint flen = vfield->len; ulint flen = vfield->len;
if (flen != UNIV_SQL_NULL) { if (flen != UNIV_SQL_NULL) {
@ -1331,8 +1330,6 @@ already_logged:
for (col_no = 0; col_no < dict_table_get_n_v_cols(table); for (col_no = 0; col_no < dict_table_get_n_v_cols(table);
col_no++) { col_no++) {
dfield_t* vfield = NULL;
const dict_v_col_t* col const dict_v_col_t* col
= dict_table_get_nth_v_col(table, col_no); = dict_table_get_nth_v_col(table, col_no);
@ -1362,6 +1359,8 @@ already_logged:
return(0); return(0);
} }
const dfield_t* vfield = NULL;
if (update) { if (update) {
ut_ad(!row); ut_ad(!row);
if (update->old_vrow == NULL) { if (update->old_vrow == NULL) {
@ -2300,7 +2299,7 @@ trx_undo_prev_version_build(
dtuple if it is not yet created. This heap dtuple if it is not yet created. This heap
diffs from "heap" above in that it could be diffs from "heap" above in that it could be
prebuilt->old_vers_heap for selection */ prebuilt->old_vers_heap for selection */
const dtuple_t**vrow, /*!< out: virtual column info, if any */ dtuple_t** vrow, /*!< out: virtual column info, if any */
ulint v_status) ulint v_status)
/*!< in: status determine if it is going /*!< in: status determine if it is going
into this function by purge thread or not. into this function by purge thread or not.
@ -2503,7 +2502,7 @@ void
trx_undo_read_v_cols( trx_undo_read_v_cols(
const dict_table_t* table, const dict_table_t* table,
const byte* ptr, const byte* ptr,
const dtuple_t* row, dtuple_t* row,
bool in_purge) bool in_purge)
{ {
const byte* end_ptr; const byte* end_ptr;