<commit_before>/******************************************************
Row versions

(c) 1997 <NAME>

Created 2/6/1997 <NAME>
*******************************************************/

#include "row0vers.h"

#ifdef UNIV_NONINL
#include "row0vers.ic"
#endif

#include "dict0dict.h"
#include "dict0boot.h"
#include "btr0btr.h"
#include "mach0data.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "trx0roll.h"
#include "trx0undo.h"
#include "trx0purge.h"
#include "trx0rec.h"
#include "que0que.h"
#include "row0row.h"
#include "row0upd.h"
#include "rem0cmp.h"
#include "read0read.h"
#include "lock0lock.h"

/*********************************************************************
Finds out if an active transaction has inserted or modified a secondary
index record. NOTE: the kernel mutex is temporarily released in this
function! */

trx_t*
row_vers_impl_x_locked_off_kernel(
/*==============================*/
				/* out: NULL if committed, else the active
				transaction; NOTE that the kernel mutex is
				temporarily released! */
	rec_t*		rec,	/* in: record in a secondary index */
	dict_index_t*	index)	/* in: the secondary index */
{
	dict_index_t*	clust_index;
	rec_t*		clust_rec;
	rec_t*		version;
	rec_t*		prev_version;
	dulint		trx_id;
	dulint		prev_trx_id;
	mem_heap_t*	heap;
	mem_heap_t*	heap2;
	dtuple_t*	row;
	dtuple_t*	entry	= NULL; /* assignment to eliminate compiler
					warning */
	trx_t*		trx;
	ibool		vers_del;
	ibool		rec_del;
	ulint		err;
	mtr_t		mtr;
	
	ut_ad(mutex_own(&kernel_mutex));
	ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));

	mutex_exit(&kernel_mutex);

	mtr_start(&mtr);
	
	/* Search for the clustered index record: this is a time-consuming
	operation: therefore we release the kernel mutex; also, the release
	is required by the latching order convention. The latch on the
	clustered index locks the top of the stack of versions. We also
	reserve purge_latch to lock the bottom of the version stack. */	

	clust_rec = row_get_clust_rec(BTR_SEARCH_LEAF, rec, index,
							&clust_index, &mtr);
	if (!clust_rec) {
		/* In a rare case it is possible that no clust rec is found
		for a secondary index record: if in row0umod.c
		row_undo_mod_remove_clust_low() we have already removed the
		clust rec, while purge is still cleaning and removing
		secondary index records associated with earlier versions of
		the clustered index record. In that case there cannot be
		any implicit lock on the secondary index record, because
		an active transaction which has modified the secondary index
		record has also modified the clustered index record. And in
		a rollback we always undo the modifications to secondary index
		records before the clustered index record. */

		mtr_commit(&mtr);

	        return(NULL);
	}

	trx_id = row_get_rec_trx_id(clust_rec, clust_index);

	mtr_s_lock(&(purge_sys->latch), &mtr);

	mutex_enter(&kernel_mutex);
	
	if (!trx_is_active(trx_id)) {
		/* The transaction that modified or inserted clust_rec is no
		longer active: no implicit lock on rec */
		
		mtr_commit(&mtr);

		return(NULL);
	}

	if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index, TRUE)) {
		/* Corruption noticed: try to avoid a crash by returning */
		
		mtr_commit(&mtr);<commit_msg>row0vers.c:   Add forgotten mutex_enter()<commit_after>/******************************************************
Row versions

(c) 1997 <NAME>

Created 2/6/1997 <NAME>
*******************************************************/

#include "row0vers.h"

#ifdef UNIV_NONINL
#include "row0vers.ic"
#endif

#include "dict0dict.h"
#include "dict0boot.h"
#include "btr0btr.h"
#include "mach0data.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "trx0roll.h"
#include "trx0undo.h"
#include "trx0purge.h"
#include "trx0rec.h"
#include "que0que.h"
#include "row0row.h"
#include "row0upd.h"
#include "rem0cmp.h"
#include "read0read.h"
#include "lock0lock.h"

/*********************************************************************
Finds out if an active transaction has inserted or modified a secondary
index record. NOTE: the kernel mutex is temporarily released in this
function! */

trx_t*
row_vers_impl_x_locked_off_kernel(
/*==============================*/
				/* out: NULL if committed, else the active
				transaction; NOTE that the kernel mutex is
				temporarily released! */
	rec_t*		rec,	/* in: record in a secondary index */
	dict_index_t*	index)	/* in: the secondary index */
{
	dict_index_t*	clust_index;
	rec_t*		clust_rec;
	rec_t*		version;
	rec_t*		prev_version;
	dulint		trx_id;
	dulint		prev_trx_id;
	mem_heap_t*	heap;
	mem_heap_t*	heap2;
	dtuple_t*	row;
	dtuple_t*	entry	= NULL; /* assignment to eliminate compiler
					warning */
	trx_t*		trx;
	ibool		vers_del;
	ibool		rec_del;
	ulint		err;
	mtr_t		mtr;
	
	ut_ad(mutex_own(&kernel_mutex));
	ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));

	mutex_exit(&kernel_mutex);

	mtr_start(&mtr);
	
	/* Search for the clustered index record: this is a time-consuming
	operation: therefore we release the kernel mutex; also, the release
	is required by the latching order convention. The latch on the
	clustered index locks the top of the stack of versions. We also
	reserve purge_latch to lock the bottom of the version stack. */	

	clust_rec = row_get_clust_rec(BTR_SEARCH_LEAF, rec, index,
							&clust_index, &mtr);
	if (!clust_rec) {
		/* In a rare case it is possible that no clust rec is found
		for a secondary index record: if in row0umod.c
		row_undo_mod_remove_clust_low() we have already removed the
		clust rec, while purge is still cleaning and removing
		secondary index records associated with earlier versions of
		the clustered index record. In that case there cannot be
		any implicit lock on the secondary index record, because
		an active transaction which has modified the secondary index
		record has also modified the clustered index record. And in
		a rollback we always undo the modifications to secondary index
		records before the clustered index record. */

		mutex_enter(&kernel_mutex);
		mtr_commit(&mtr);

	        return(NULL);
	}

	trx_id = row_get_rec_trx_id(clust_rec, clust_index);

	mtr_s_lock(&(purge_sys->latch), &mtr);

	mutex_enter(&kernel_mutex);
	
	if (!trx_is_active(trx_id)) {
		/* The transaction that modified or inserted clust_rec is no
		longer active: no implicit lock on rec */
		
		mtr_commit(&mtr);

		return(NULL);
	}

	if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index, TRUE)) {
		/* Corruption noticed: try to avoid a crash by returning */
		
		mtr_commit(&mtr);
{'fraction_non_alphanumeric': 0.15078148942690775, 'fraction_numerical': 0.009347226478700583, 'mean_word_length': 4.646193771626297, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6475795', 'n_tokens_mistral': 2427, 'n_tokens_neox': 2235, 'n_words': 699}