202 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
/*****************************************************************************
 | 
						|
 | 
						|
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
 | 
						|
 | 
						|
This program is free software; you can redistribute it and/or modify it under
 | 
						|
the terms of the GNU General Public License, version 2.0, as published by the
 | 
						|
Free Software Foundation.
 | 
						|
 | 
						|
This program is also distributed with certain software (including but not
 | 
						|
limited to OpenSSL) that is licensed under separate terms, as designated in a
 | 
						|
particular file or component or in included license documentation. The authors
 | 
						|
of MySQL hereby grant you an additional permission to link the program and
 | 
						|
your derivative works with the separately licensed software that they have
 | 
						|
included with MySQL.
 | 
						|
 | 
						|
This program is distributed in the hope that it will be useful, but WITHOUT
 | 
						|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
						|
FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
 | 
						|
for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License along with
 | 
						|
this program; if not, write to the Free Software Foundation, Inc.,
 | 
						|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 | 
						|
 | 
						|
*****************************************************************************/
 | 
						|
 | 
						|
/** @file include/row0upd.ic
 | 
						|
 Update of a row
 | 
						|
 | 
						|
 Created 12/27/1996 Heikki Tuuri
 | 
						|
 *******************************************************/
 | 
						|
 | 
						|
#include "mtr0log.h"
 | 
						|
#ifndef UNIV_HOTBACKUP
 | 
						|
#include "lock0lock.h"
 | 
						|
#include "row0row.h"
 | 
						|
#include "trx0trx.h"
 | 
						|
#include "trx0undo.h"
 | 
						|
#endif /* !UNIV_HOTBACKUP */
 | 
						|
#include "page0zip.h"
 | 
						|
#include "lizard0row.h"
 | 
						|
 | 
						|
/** Creates an update vector object.
 | 
						|
 @return own: update vector object */
 | 
						|
UNIV_INLINE
 | 
						|
upd_t *upd_create(ulint n,          /*!< in: number of fields */
 | 
						|
                  mem_heap_t *heap) /*!< in: heap from which memory allocated */
 | 
						|
{
 | 
						|
  upd_t *update;
 | 
						|
 | 
						|
  update = static_cast<upd_t *>(
 | 
						|
      mem_heap_zalloc(heap, sizeof(upd_t) + sizeof(upd_field_t) * n));
 | 
						|
 | 
						|
  update->n_fields = n;
 | 
						|
  update->fields = reinterpret_cast<upd_field_t *>(&update[1]);
 | 
						|
  update->heap = heap;
 | 
						|
 | 
						|
  for (ulint i = 0; i < n; ++i) {
 | 
						|
    upd_field_t *uf = &update->fields[i];
 | 
						|
    uf->heap = heap;
 | 
						|
  }
 | 
						|
 | 
						|
  return (update);
 | 
						|
}
 | 
						|
 | 
						|
/** Returns the number of fields in the update vector == number of columns
 | 
						|
 to be updated by an update vector.
 | 
						|
 @return number of fields */
 | 
						|
UNIV_INLINE
 | 
						|
ulint upd_get_n_fields(const upd_t *update) /*!< in: update vector */
 | 
						|
{
 | 
						|
  ut_ad(update);
 | 
						|
 | 
						|
  return (update->n_fields);
 | 
						|
}
 | 
						|
 | 
						|
#ifdef UNIV_DEBUG
 | 
						|
/** Returns the nth field of an update vector.
 | 
						|
 @return update vector field */
 | 
						|
UNIV_INLINE
 | 
						|
upd_field_t *upd_get_nth_field(
 | 
						|
    const upd_t *update, /*!< in: update vector */
 | 
						|
    ulint n)             /*!< in: field position in update vector */
 | 
						|
{
 | 
						|
  ut_ad(update);
 | 
						|
  ut_ad(n < update->n_fields);
 | 
						|
 | 
						|
  return ((upd_field_t *)update->fields + n);
 | 
						|
}
 | 
						|
#endif /* UNIV_DEBUG */
 | 
						|
 | 
						|
/** Sets an index field number to be updated by an update vector field. */
 | 
						|
UNIV_INLINE
 | 
						|
void upd_field_set_field_no(
 | 
						|
    upd_field_t *upd_field,    /*!< in: update vector field */
 | 
						|
    ulint field_no,            /*!< in: field number in a clustered
 | 
						|
                               index */
 | 
						|
    const dict_index_t *index, /*!< in: index */
 | 
						|
    trx_t *trx)                /*!< in: transaction */
 | 
						|
{
 | 
						|
  upd_field->field_no = field_no;
 | 
						|
  upd_field->orig_len = 0;
 | 
						|
 | 
						|
  if (field_no >= dict_index_get_n_fields(index)) {
 | 
						|
    ib::error(ER_IB_MSG_628)
 | 
						|
        << " trying to access field " << field_no << " in " << index->name
 | 
						|
        << " of table " << index->table->name << " which contains only "
 | 
						|
        << index->n_fields << " fields";
 | 
						|
    ut_ad(0);
 | 
						|
  }
 | 
						|
 | 
						|
  index->get_col(field_no)->copy_type(dfield_get_type(&upd_field->new_val));
 | 
						|
}
 | 
						|
 | 
						|
/** set field number to a update vector field, marks this field is updated.
 | 
						|
@param[in,out]	upd_field	update vector field
 | 
						|
@param[in]	field_no	virtual column sequence num
 | 
						|
@param[in]	index		index */
 | 
						|
UNIV_INLINE
 | 
						|
void upd_field_set_v_field_no(upd_field_t *upd_field, ulint field_no,
 | 
						|
                              const dict_index_t *index) {
 | 
						|
  upd_field->field_no = field_no;
 | 
						|
  upd_field->orig_len = 0;
 | 
						|
 | 
						|
  if (field_no >= dict_table_get_n_v_cols(index->table)) {
 | 
						|
    ib::error(ER_IB_MSG_629) << " trying to access virtual field " << field_no
 | 
						|
                             << " in " << index->name << " of table "
 | 
						|
                             << index->table->name << " which contains only "
 | 
						|
                             << index->table->n_v_cols << " virutal columns";
 | 
						|
    ut_ad(0);
 | 
						|
  }
 | 
						|
 | 
						|
  dict_table_get_nth_v_col(index->table, field_no)
 | 
						|
      ->m_col.copy_type(dfield_get_type(&upd_field->new_val));
 | 
						|
}
 | 
						|
 | 
						|
/** Returns a field of an update vector by field_no.
 | 
						|
 @return update vector field, or NULL */
 | 
						|
UNIV_INLINE
 | 
						|
const upd_field_t *upd_get_field_by_field_no(
 | 
						|
    const upd_t *update, /*!< in: update vector */
 | 
						|
    ulint no,            /*!< in: field_no */
 | 
						|
    bool is_virtual)     /*!< in: if it is virtual column */
 | 
						|
{
 | 
						|
  ulint i;
 | 
						|
  for (i = 0; i < upd_get_n_fields(update); i++) {
 | 
						|
    const upd_field_t *uf = upd_get_nth_field(update, i);
 | 
						|
 | 
						|
    /* matches only if the field matches that of is_virtual */
 | 
						|
    if ((!is_virtual) != (!upd_fld_is_virtual_col(uf))) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (uf->field_no == no) {
 | 
						|
      return (uf);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return (NULL);
 | 
						|
}
 | 
						|
 | 
						|
#ifndef UNIV_HOTBACKUP
 | 
						|
/** Updates the trx id and roll ptr field in a clustered index record when
 | 
						|
 a row is updated or marked deleted. */
 | 
						|
UNIV_INLINE
 | 
						|
void row_upd_rec_sys_fields(
 | 
						|
    rec_t *rec,                /*!< in/out: record */
 | 
						|
    page_zip_des_t *page_zip,  /*!< in/out: compressed page whose
 | 
						|
                              uncompressed part will be updated, or NULL */
 | 
						|
    const dict_index_t *index, /*!< in: clustered index */
 | 
						|
    const ulint *offsets,      /*!< in: rec_get_offsets(rec, index) */
 | 
						|
    const trx_t *trx,          /*!< in: transaction */
 | 
						|
    roll_ptr_t roll_ptr)       /*!< in: roll ptr of the undo log record,
 | 
						|
                       can be 0 during IMPORT */
 | 
						|
{
 | 
						|
  ut_ad(index->is_clustered());
 | 
						|
  ut_ad(rec_offs_validate(rec, index, offsets));
 | 
						|
 | 
						|
  if (page_zip) {
 | 
						|
    ulint pos = index->get_sys_col_pos(DATA_TRX_ID);
 | 
						|
    page_zip_write_trx_id_and_roll_ptr(page_zip, rec, offsets, pos, trx->id,
 | 
						|
                                       roll_ptr);
 | 
						|
  } else {
 | 
						|
    ulint offset = index->trx_id_offset;
 | 
						|
 | 
						|
    if (!offset) {
 | 
						|
      offset = row_get_trx_id_offset(index, offsets);
 | 
						|
    }
 | 
						|
 | 
						|
    /* During IMPORT the trx id in the record can be in the
 | 
						|
    future, if the .ibd file is being imported from another
 | 
						|
    instance. During IMPORT roll_ptr will be 0. */
 | 
						|
    ut_ad(roll_ptr == 0 ||
 | 
						|
          lock_check_trx_id_sanity(trx_read_trx_id(rec + offset), rec, index,
 | 
						|
                                   offsets));
 | 
						|
 | 
						|
    trx_write_trx_id(rec + offset, trx->id);
 | 
						|
    trx_write_roll_ptr(rec + offset + DATA_TRX_ID_LEN, roll_ptr);
 | 
						|
  }
 | 
						|
}
 | 
						|
#endif /* !UNIV_HOTBACKUP */
 |