⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 row0upd.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
	Therefore we can assert that the restoration of the cursor succeeds. */	ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));	ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),					index->table->comp));		err = btr_cur_pessimistic_update(BTR_NO_LOCKING_FLAG, btr_cur,					&big_rec, node->update,					node->cmpl_info, thr, mtr);	mtr_commit(mtr);	if (err == DB_SUCCESS && big_rec) {		mem_heap_t*	heap		= NULL;		ulint		offsets_[REC_OFFS_NORMAL_SIZE];		rec_t*		rec;		*offsets_ = (sizeof offsets_) / sizeof *offsets_;		mtr_start(mtr);		ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));		rec = btr_cur_get_rec(btr_cur);		err = btr_store_big_rec_extern_fields(index, rec,			rec_get_offsets(rec, index, offsets_,				ULINT_UNDEFINED, &heap),			big_rec, mtr);		if (UNIV_LIKELY_NULL(heap)) {			mem_heap_free(heap);		}		mtr_commit(mtr);	}	if (big_rec) {		dtuple_big_rec_free(big_rec);	}			return(err);}/***************************************************************Delete marks a clustered index record. */staticulintrow_upd_del_mark_clust_rec(/*=======================*/				/* out: DB_SUCCESS if operation successfully				completed, else error code */	upd_node_t*	node,	/* in: row update node */	dict_index_t*	index,	/* in: clustered index */	que_thr_t*	thr,	/* in: query thread */	ibool		check_ref,/* in: TRUE if index may be referenced in				a foreign key constraint */	mtr_t*		mtr)	/* in: mtr; gets committed here */{	btr_pcur_t*	pcur;	btr_cur_t*	btr_cur;	ulint		err;		ut_ad(node);	ut_ad(index->type & DICT_CLUSTERED);	ut_ad(node->is_delete);	pcur = node->pcur;	btr_cur = btr_pcur_get_btr_cur(pcur);	/* Store row because we have to build also the secondary index	entries */		row_upd_store_row(node);	/* Mark the clustered index record deleted; we do not have to check	locks, because we assume that we have an x-lock on the record */	err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,						btr_cur, TRUE, thr, mtr);	if (err == DB_SUCCESS && check_ref) {		/* NOTE that the following call loses the position of pcur ! */		err = row_upd_check_references_constraints(node,							pcur, index->table,							index, thr, mtr);		if (err != DB_SUCCESS) {			mtr_commit(mtr);			return(err);		}	}	mtr_commit(mtr);		return(err);}/***************************************************************Updates the clustered index record. */staticulintrow_upd_clust_step(/*===============*/				/* out: DB_SUCCESS if operation successfully				completed, DB_LOCK_WAIT in case of a lock wait,				else error code */	upd_node_t*	node,	/* in: row update node */	que_thr_t*	thr)	/* in: query thread */{	dict_index_t*	index;	btr_pcur_t*	pcur;	ibool		success;	ibool		check_ref;	ulint		err;	mtr_t*		mtr;	mtr_t		mtr_buf;	rec_t*		rec;	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	const ulint*	offsets;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	index = dict_table_get_first_index(node->table);	check_ref = row_upd_index_is_referenced(index, thr_get_trx(thr));	pcur = node->pcur;	/* We have to restore the cursor to its position */	mtr = &mtr_buf;	mtr_start(mtr);		/* If the restoration does not succeed, then the same	transaction has deleted the record on which the cursor was,	and that is an SQL error. If the restoration succeeds, it may	still be that the same transaction has successively deleted	and inserted a record with the same ordering fields, but in	that case we know that the transaction has at least an	implicit x-lock on the record. */		ut_a(pcur->rel_pos == BTR_PCUR_ON);	success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr);	if (!success) {		err = DB_RECORD_NOT_FOUND;		mtr_commit(mtr);		return(err);	}	/* If this is a row in SYS_INDEXES table of the data dictionary,	then we have to free the file segments of the index tree associated	with the index */	if (node->is_delete	    && ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {		dict_drop_index_tree(btr_pcur_get_rec(pcur), mtr);		mtr_commit(mtr);		mtr_start(mtr);		success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,									mtr);		if (!success) {			err = DB_ERROR;			mtr_commit(mtr);			return(err);		}	} 	rec = btr_pcur_get_rec(pcur);	offsets = rec_get_offsets(rec, index, offsets_,						ULINT_UNDEFINED, &heap);	if (!node->has_clust_rec_x_lock) {		err = lock_clust_rec_modify_check_and_lock(0,						rec, index, offsets, thr);		if (err != DB_SUCCESS) {			mtr_commit(mtr);			goto exit_func;		}	}	/* NOTE: the following function calls will also commit mtr */	if (node->is_delete) {		err = row_upd_del_mark_clust_rec(node, index, thr, check_ref,									mtr);		if (err == DB_SUCCESS) {			node->state = UPD_NODE_UPDATE_ALL_SEC;			node->index = dict_table_get_next_index(index);		}	exit_func:		if (UNIV_LIKELY_NULL(heap)) {			mem_heap_free(heap);		}		return(err);	}		/* If the update is made for MySQL, we already have the update vector	ready, else we have to do some evaluation: */ 	if (!node->in_mysql_interface) {		/* Copy the necessary columns from clust_rec and calculate the		new values to set */		row_upd_copy_columns(rec, offsets,					UT_LIST_GET_FIRST(node->columns));		row_upd_eval_new_vals(node->update);	}	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}			if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) {		err = row_upd_clust_rec(node, index, thr, mtr);		return(err);	}		row_upd_store_row(node);	if (row_upd_changes_ord_field_binary(node->row, index, node->update)) {		/* Update causes an ordering field (ordering fields within		the B-tree) of the clustered index record to change: perform		the update by delete marking and inserting.		TODO! What to do to the 'Halloween problem', where an update		moves the record forward in index so that it is again		updated when the cursor arrives there? Solution: the		read operation must check the undo record undo number when		choosing records to update. MySQL solves now the problem		externally! */		err = row_upd_clust_rec_by_insert(node, index, thr, check_ref,									mtr);		if (err != DB_SUCCESS) {			return(err);		}		node->state = UPD_NODE_UPDATE_ALL_SEC;	} else {		err = row_upd_clust_rec(node, index, thr, mtr);		if (err != DB_SUCCESS) {			return(err);		}		node->state = UPD_NODE_UPDATE_SOME_SEC;	}	node->index = dict_table_get_next_index(index);	return(err);}/***************************************************************Updates the affected index records of a row. When the control is transferredto this node, we assume that we have a persistent cursor which was on arecord, and the position of the cursor is stored in the cursor. */staticulintrow_upd(/*====*/				/* out: DB_SUCCESS if operation successfully				completed, else error code or DB_LOCK_WAIT */	upd_node_t*	node,	/* in: row update node */	que_thr_t*	thr)	/* in: query thread */{	ulint	err	= DB_SUCCESS;		ut_ad(node && thr);	if (node->in_mysql_interface) {			/* We do not get the cmpl_info value from the MySQL		interpreter: we must calculate it on the fly: */				if (node->is_delete ||			row_upd_changes_some_index_ord_field_binary(					node->table, node->update)) {			node->cmpl_info = 0; 		} else {			node->cmpl_info = UPD_NODE_NO_ORD_CHANGE;		}	}	if (node->state == UPD_NODE_UPDATE_CLUSTERED				|| node->state == UPD_NODE_INSERT_CLUSTERED) {		err = row_upd_clust_step(node, thr);				if (err != DB_SUCCESS) {			goto function_exit;		}	}	if (!node->is_delete && (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {		goto function_exit;	}	while (node->index != NULL) {		err = row_upd_sec_step(node, thr);		if (err != DB_SUCCESS) {			goto function_exit;		}		node->index = dict_table_get_next_index(node->index);        }function_exit:	if (err == DB_SUCCESS) {		/* Do some cleanup */		if (node->row != NULL) {			node->row = NULL;			node->n_ext_vec = 0;			mem_heap_empty(node->heap);		}		node->state = UPD_NODE_UPDATE_CLUSTERED;	}        return(err);}/***************************************************************Updates a row in a table. This is a high-level function used in SQL executiongraphs. */que_thr_t*row_upd_step(/*=========*/				/* out: query thread to run next or NULL */	que_thr_t*	thr)	/* in: query thread */{	upd_node_t*	node;	sel_node_t*	sel_node;	que_node_t*	parent;	ulint		err		= DB_SUCCESS;	trx_t*		trx;	ut_ad(thr);		trx = thr_get_trx(thr);	trx_start_if_not_started(trx);	node = thr->run_node;		sel_node = node->select;	parent = que_node_get_parent(node);		ut_ad(que_node_get_type(node) == QUE_NODE_UPDATE);		if (thr->prev_node == parent) {		node->state = UPD_NODE_SET_IX_LOCK;	}	if (node->state == UPD_NODE_SET_IX_LOCK) {		if (!node->has_clust_rec_x_lock) {			/* It may be that the current session has not yet			started its transaction, or it has been committed: */			err = lock_table(0, node->table, LOCK_IX, thr);			if (err != DB_SUCCESS) {				goto error_handling;			}		}			node->state = UPD_NODE_UPDATE_CLUSTERED;		if (node->searched_update) {			/* Reset the cursor */			sel_node->state = SEL_NODE_OPEN;					/* Fetch a row to update */					thr->run_node = sel_node;				return(thr);		}	}	/* sel_node is NULL if we are in the MySQL interface */		if (sel_node && (sel_node->state != SEL_NODE_FETCH)) {		if (!node->searched_update) {			/* An explicit cursor should be positioned on a row			to update */			ut_error;						err = DB_ERROR;			goto error_handling;		}		ut_ad(sel_node->state == SEL_NODE_NO_MORE_ROWS);		/* No more rows to update, or the select node performed the		updates directly in-place */		thr->run_node = parent;			return(thr);	}	/* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */		err = row_upd(node, thr);error_handling:	trx->error_state = err;	if (err == DB_SUCCESS) {		/* Ok: do nothing */	} else if (err == DB_LOCK_WAIT) {		return(NULL);	} else {		return(NULL);	}	/* DO THE TRIGGER ACTIONS HERE */	if (node->searched_update) {		/* Fetch next row to update */		thr->run_node = sel_node;	} else {		/* It was an explicit cursor update */		thr->run_node = parent;	}	node->state = UPD_NODE_UPDATE_CLUSTERED;	return(thr);} /*************************************************************************Performs an in-place update for the current clustered index record inselect. */voidrow_upd_in_place_in_select(/*=======================*/	sel_node_t*	sel_node,	/* in: select node */	que_thr_t*	thr,		/* in: query thread */	mtr_t*		mtr)		/* in: mtr */{	upd_node_t*	node;	btr_pcur_t*	pcur;	btr_cur_t*	btr_cur;	ulint		err;	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	ut_ad(sel_node->select_will_do_update);	ut_ad(sel_node->latch_mode == BTR_MODIFY_LEAF);	ut_ad(sel_node->asc);	node = que_node_get_parent(sel_node);	ut_ad(que_node_get_type(node) == QUE_NODE_UPDATE);	pcur = node->pcur;	btr_cur = btr_pcur_get_btr_cur(pcur);	/* Copy the necessary columns from clust_rec and calculate the new	values to set */	row_upd_copy_columns(btr_pcur_get_rec(pcur), rec_get_offsets(			btr_pcur_get_rec(pcur), btr_cur->index, offsets_,			ULINT_UNDEFINED, &heap),		UT_LIST_GET_FIRST(node->columns));	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}	row_upd_eval_new_vals(node->update);	ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),					btr_cur->index->table->comp));		ut_ad(node->cmpl_info & UPD_NODE_NO_SIZE_CHANGE);	ut_ad(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE);	ut_ad(node->select_will_do_update);	err = btr_cur_update_in_place(BTR_NO_LOCKING_FLAG, btr_cur,						node->update, node->cmpl_info,						thr, mtr);	ut_ad(err == DB_SUCCESS);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -