mariadb/storage/innobase/include/ha0ha.ic
tsmith@siva.hindu.god baddc4e91c Apply the following InnoDB snapshots:
innodb-5.1-ss1318
innodb-5.1-ss1330
innodb-5.1-ss1332
innodb-5.1-ss1340

Fixes:
- Bug #21409: Incorrect result returned when in READ-COMMITTED with query_cache ON
  At low transaction isolation levels we let each consistent read set
  its own snapshot.

- Bug #23666: strange Innodb_row_lock_time_% values in show status; also millisecs wrong
  On Windows ut_usectime returns secs and usecs relative to the UNIX
  epoch (which is Jan, 1 1970).

- Bug #25494: LATEST DEADLOCK INFORMATION is not always cleared
  lock_deadlock_recursive(): When the search depth or length is exceeded,
  rewind lock_latest_err_file and display the two transactions at the
  point of aborting the search.

- Bug #25927: Foreign key with ON DELETE SET NULL on NOT NULL can crash server
  Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns for which
  there is a foreign key constraint ON ... SET NULL.

- Bug #26835: Repeatable corruption of utf8-enabled tables inside InnoDB
  The bug could be reproduced as follows:

  Define a table so that the first column of the clustered index is
  a VARCHAR or a UTF-8 CHAR in a collation where sequences of bytes
  of differing length are considered equivalent.

  Insert and delete a record.  Before the delete-marked record is
  purged, insert another record whose first column is of different
  length but equivalent to the first record.  Under certain conditions,
  the insertion can be incorrectly performed as update-in-place.

  Likewise, an operation that could be done as update-in-place can
  unnecessarily be performed as delete and insert, but that would not
  cause corruption but merely degraded performance.
2007-03-22 15:59:35 -06:00

185 lines
4.2 KiB
Text

/************************************************************************
The hash table with external chains
(c) 1994-1997 Innobase Oy
Created 8/18/1994 Heikki Tuuri
*************************************************************************/
#include "ut0rnd.h"
#include "mem0mem.h"
/***************************************************************
Deletes a hash node. */
void
ha_delete_hash_node(
/*================*/
hash_table_t* table, /* in: hash table */
ha_node_t* del_node); /* in: node to be deleted */
/**********************************************************************
Gets a hash node data. */
UNIV_INLINE
void*
ha_node_get_data(
/*=============*/
/* out: pointer to the data */
ha_node_t* node) /* in: hash chain node */
{
return(node->data);
}
/**********************************************************************
Sets hash node data. */
UNIV_INLINE
void
ha_node_set_data(
/*=============*/
ha_node_t* node, /* in: hash chain node */
void* data) /* in: pointer to the data */
{
node->data = data;
}
/**********************************************************************
Gets the next node in a hash chain. */
UNIV_INLINE
ha_node_t*
ha_chain_get_next(
/*==============*/
/* out: next node, NULL if none */
ha_node_t* node) /* in: hash chain node */
{
return(node->next);
}
/**********************************************************************
Gets the first node in a hash chain. */
UNIV_INLINE
ha_node_t*
ha_chain_get_first(
/*===============*/
/* out: first node, NULL if none */
hash_table_t* table, /* in: hash table */
ulint fold) /* in: fold value determining the chain */
{
return(hash_get_nth_cell(table, hash_calc_hash(fold, table))->node);
}
/*****************************************************************
Looks for an element in a hash table. */
UNIV_INLINE
ha_node_t*
ha_search(
/*======*/
/* out: pointer to the first hash table node
in chain having the fold number, NULL if not
found */
hash_table_t* table, /* in: hash table */
ulint fold) /* in: folded value of the searched data */
{
ha_node_t* node;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
node = ha_chain_get_first(table, fold);
while (node) {
if (node->fold == fold) {
return(node);
}
node = ha_chain_get_next(node);
}
return(NULL);
}
/*****************************************************************
Looks for an element in a hash table. */
UNIV_INLINE
void*
ha_search_and_get_data(
/*===================*/
/* out: pointer to the data of the first hash
table node in chain having the fold number,
NULL if not found */
hash_table_t* table, /* in: hash table */
ulint fold) /* in: folded value of the searched data */
{
ha_node_t* node;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
node = ha_chain_get_first(table, fold);
while (node) {
if (node->fold == fold) {
return(node->data);
}
node = ha_chain_get_next(node);
}
return(NULL);
}
/*************************************************************
Looks for an element when we know the pointer to the data. */
UNIV_INLINE
ha_node_t*
ha_search_with_data(
/*================*/
/* out: pointer to the hash table node, NULL
if not found in the table */
hash_table_t* table, /* in: hash table */
ulint fold, /* in: folded value of the searched data */
void* data) /* in: pointer to the data */
{
ha_node_t* node;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
node = ha_chain_get_first(table, fold);
while (node) {
if (node->data == data) {
return(node);
}
node = ha_chain_get_next(node);
}
return(NULL);
}
/*************************************************************
Looks for an element when we know the pointer to the data, and deletes
it from the hash table, if found. */
UNIV_INLINE
ibool
ha_search_and_delete_if_found(
/*==========================*/
/* out: TRUE if found */
hash_table_t* table, /* in: hash table */
ulint fold, /* in: folded value of the searched data */
void* data) /* in: pointer to the data */
{
ha_node_t* node;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
node = ha_search_with_data(table, fold, data);
if (node) {
ha_delete_hash_node(table, node);
return(TRUE);
}
return(FALSE);
}