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

📄 row0upd.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
	ut_ad(update && index);	n_unique = dict_index_get_n_unique(index);	n_upd_fields = upd_get_n_fields(update);	for (i = 0; i < n_unique; i++) {		ind_field = dict_index_get_nth_field(index, i);		col = dict_field_get_col(ind_field);		col_pos = dict_col_get_clust_pos(col);		col_no = dict_col_get_no(col);		for (j = 0; j < n_upd_fields; j++) {			upd_field = upd_get_nth_field(update, j);			/* Note that if the index field is a column prefix			then it may be that row does not contain an externally			stored part of the column value, and we cannot compare			the datas */			if (col_pos == upd_field->field_no			    && (row == NULL			        || ind_field->prefix_len > 0				|| !dfield_datas_are_binary_equal(					dtuple_get_nth_field(row, col_no),						&(upd_field->new_val)))) {				return(TRUE);			}		}	}	return(FALSE);}/***************************************************************Checks if an update vector changes an ordering field of an index record.NOTE: we compare the fields as binary strings! */iboolrow_upd_changes_some_index_ord_field_binary(/*========================================*/				/* out: TRUE if update vector may change				an ordering field in an index record */	dict_table_t*	table,	/* in: table */	upd_t*		update)	/* in: update vector for the row */{	upd_field_t*	upd_field;	dict_index_t*	index;	ulint		i;		index = dict_table_get_first_index(table);		for (i = 0; i < upd_get_n_fields(update); i++) {		upd_field = upd_get_nth_field(update, i);		if (dict_field_get_col(dict_index_get_nth_field(index,						upd_field->field_no))		    ->ord_part) {		    	return(TRUE);		}	}		return(FALSE);}/***************************************************************Checks if an update vector changes some of the first ordering fields of anindex record. This is only used in foreign key checks and we can assumethat index does not contain column prefixes. */staticiboolrow_upd_changes_first_fields_binary(/*================================*/				/* out: TRUE if changes */	dtuple_t*	entry,	/* in: index entry */	dict_index_t*	index,	/* in: index of entry */	upd_t*		update,	/* in: update vector for the row */	ulint		n)	/* in: how many first fields to check */{	upd_field_t*	upd_field;	dict_field_t*	ind_field;	dict_col_t*	col;	ulint		n_upd_fields;	ulint		col_pos;	ulint		i, j;		ut_a(update && index);	ut_a(n <= dict_index_get_n_fields(index));		n_upd_fields = upd_get_n_fields(update);	for (i = 0; i < n; i++) {		ind_field = dict_index_get_nth_field(index, i);		col = dict_field_get_col(ind_field);		col_pos = dict_col_get_clust_pos(col);		ut_a(ind_field->prefix_len == 0);		for (j = 0; j < n_upd_fields; j++) {			upd_field = upd_get_nth_field(update, j);			if (col_pos == upd_field->field_no			    && !dfield_datas_are_binary_equal(					     dtuple_get_nth_field(entry, i),					     &(upd_field->new_val))) {				return(TRUE);			}		}	}	return(FALSE);}/*************************************************************************Copies the column values from a record. */UNIV_INLINEvoidrow_upd_copy_columns(/*=================*/	rec_t*		rec,	/* in: record in a clustered index */	const ulint*	offsets,/* in: array returned by rec_get_offsets() */	sym_node_t*	column)	/* in: first column in a column list, or				NULL */{	byte*	data;	ulint	len;	while (column) {		data = rec_get_nth_field(rec, offsets,					column->field_nos[SYM_CLUST_FIELD_NO],									&len);		eval_node_copy_and_alloc_val(column, data, len);		column = UT_LIST_GET_NEXT(col_var_list, column);	}}/*************************************************************************Calculates the new values for fields to update. Note that row_upd_copy_columnsmust have been called first. */UNIV_INLINEvoidrow_upd_eval_new_vals(/*==================*/	upd_t*	update)	/* in: update vector */{	que_node_t*	exp;	upd_field_t*	upd_field;	ulint		n_fields;	ulint		i;	n_fields = upd_get_n_fields(update);	for (i = 0; i < n_fields; i++) {		upd_field = upd_get_nth_field(update, i);		exp = upd_field->exp;		eval_exp(exp);		dfield_copy_data(&(upd_field->new_val), que_node_get_val(exp));	}}/***************************************************************Stores to the heap the row on which the node->pcur is positioned. */staticvoidrow_upd_store_row(/*==============*/	upd_node_t*	node)	/* in: row update node */{	dict_index_t*	clust_index;	upd_t*		update;	rec_t*		rec;	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	const ulint*	offsets;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES);	if (node->row != NULL) {		mem_heap_empty(node->heap);		node->row = NULL;	}		clust_index = dict_table_get_first_index(node->table);	rec = btr_pcur_get_rec(node->pcur);		offsets = rec_get_offsets(rec, clust_index, offsets_,						ULINT_UNDEFINED, &heap);	node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,								node->heap);	node->ext_vec = mem_heap_alloc(node->heap, sizeof(ulint)					* rec_offs_n_fields(offsets));	if (node->is_delete) {		update = NULL;	} else {		update = node->update;	}		node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec,						offsets, update);	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}}/***************************************************************Updates a secondary index entry of a row. */staticulintrow_upd_sec_index_entry(/*====================*/				/* 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 */{	ibool		check_ref;	ibool		found;	dict_index_t*	index;	dtuple_t*	entry;	btr_pcur_t	pcur;	btr_cur_t*	btr_cur;	mem_heap_t*	heap;	rec_t*		rec;	ulint		err	= DB_SUCCESS;	mtr_t		mtr;	trx_t*		trx	= thr_get_trx(thr);	index = node->index;		check_ref = row_upd_index_is_referenced(index, trx);	heap = mem_heap_create(1024);	/* Build old index entry */	entry = row_build_index_entry(node->row, index, heap);	log_free_check();	mtr_start(&mtr);		found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,									&mtr);	btr_cur = btr_pcur_get_btr_cur(&pcur);	rec = btr_cur_get_rec(btr_cur);	if (UNIV_UNLIKELY(!found)) {		fputs("InnoDB: error in sec index entry update in\n"			"InnoDB: ", stderr);		dict_index_name_print(stderr, trx, index);		fputs("\n"			"InnoDB: tuple ", stderr);		dtuple_print(stderr, entry);		fputs("\n"			"InnoDB: record ", stderr);		rec_print(stderr, rec, index);		putc('\n', stderr);		trx_print(stderr, trx, 0);		fputs("\n""InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);	} else { 	  	/* Delete mark the old index record; it can already be          	delete marked if we return after a lock wait in          	row_ins_index_entry below */		if (!rec_get_deleted_flag(rec, index->table->comp)) {			err = btr_cur_del_mark_set_sec_rec(0, 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) {					goto close_cur;				}			}	  	}	}close_cur:	btr_pcur_close(&pcur);	mtr_commit(&mtr);	if (node->is_delete || err != DB_SUCCESS) {		mem_heap_free(heap);	        	return(err);	}	/* Build a new index entry */	row_upd_index_replace_new_col_vals(entry, index, node->update, NULL);	/* Insert new index entry */	err = row_ins_index_entry(index, entry, NULL, 0, thr);	mem_heap_free(heap);	        return(err);}/***************************************************************Updates secondary index record if it is changed in the row update. Thisshould be quite rare in database applications. */UNIV_INLINEulintrow_upd_sec_step(/*=============*/				/* 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;	ut_ad((node->state == UPD_NODE_UPDATE_ALL_SEC)				|| (node->state == UPD_NODE_UPDATE_SOME_SEC));	ut_ad(!(node->index->type & DICT_CLUSTERED));		if (node->state == UPD_NODE_UPDATE_ALL_SEC	    || row_upd_changes_ord_field_binary(node->row, node->index,							   node->update)) {		err = row_upd_sec_index_entry(node, thr);		return(err);	}	return(DB_SUCCESS);}/***************************************************************Marks the clustered index record deleted and inserts the updated versionof the record to the index. This function should be used when the orderingfields of the clustered index record change. This should be quite rare indatabase applications. */staticulintrow_upd_clust_rec_by_insert(/*========================*/				/* out: DB_SUCCESS if operation successfully				completed, else error code or DB_LOCK_WAIT */	upd_node_t*	node,	/* in: row update node */	dict_index_t*	index,	/* in: clustered index of the record */	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 */{	mem_heap_t*	heap	= NULL;	btr_pcur_t*	pcur;	btr_cur_t*	btr_cur;	trx_t*		trx;	dict_table_t*	table;	dtuple_t*	entry;	ulint		err;		ut_ad(node);	ut_ad(index->type & DICT_CLUSTERED);	trx = thr_get_trx(thr);	table = node->table;	pcur = node->pcur;	btr_cur	= btr_pcur_get_btr_cur(pcur);		if (node->state != UPD_NODE_INSERT_CLUSTERED) {		ulint	offsets_[REC_OFFS_NORMAL_SIZE];		*offsets_ = (sizeof offsets_) / sizeof *offsets_;		err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,						btr_cur, TRUE, thr, mtr);		if (err != DB_SUCCESS) {			mtr_commit(mtr);			return(err);		}		/* Mark as not-owned the externally stored fields which the new		row inherits from the delete marked record: purge should not		free those externally stored fields even if the delete marked		record is removed from the index tree, or updated. */		btr_cur_mark_extern_inherited_fields(btr_cur_get_rec(btr_cur),				rec_get_offsets(btr_cur_get_rec(btr_cur),				dict_table_get_first_index(table), offsets_,				ULINT_UNDEFINED, &heap), node->update, mtr);		if (check_ref) {			/* NOTE that the following call loses			the position of pcur ! */			err = row_upd_check_references_constraints(node,							pcur, table,							index, thr, mtr);			if (err != DB_SUCCESS) {				mtr_commit(mtr);				if (UNIV_LIKELY_NULL(heap)) {					mem_heap_free(heap);				}				return(err);			}		}	} 	mtr_commit(mtr);	if (!heap) {		heap = mem_heap_create(500);	}	node->state = UPD_NODE_INSERT_CLUSTERED;	entry = row_build_index_entry(node->row, index, heap);	row_upd_index_replace_new_col_vals(entry, index, node->update, NULL);		row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id);		/* If we return from a lock wait, for example, we may have	extern fields marked as not-owned in entry (marked in the	if-branch above). We must unmark them. */		btr_cur_unmark_dtuple_extern_fields(entry, node->ext_vec,							node->n_ext_vec);	/* We must mark non-updated extern fields in entry as inherited,	so that a possible rollback will not free them */		btr_cur_mark_dtuple_inherited_extern(entry, node->ext_vec,						node->n_ext_vec,						node->update);		err = row_ins_index_entry(index, entry, node->ext_vec,						node->n_ext_vec, thr);	mem_heap_free(heap);		return(err);}/***************************************************************Updates a clustered index record of a row when the ordering fields donot change. */staticulintrow_upd_clust_rec(/*==============*/				/* out: DB_SUCCESS if operation successfully				completed, else error code or DB_LOCK_WAIT */	upd_node_t*	node,	/* in: row update node */	dict_index_t*	index,	/* in: clustered index */	que_thr_t*	thr,	/* in: query thread */	mtr_t*		mtr)	/* in: mtr; gets committed here */{	big_rec_t*	big_rec	= NULL;	btr_pcur_t*	pcur;	btr_cur_t*	btr_cur;	ulint		err;		ut_ad(node);	ut_ad(index->type & DICT_CLUSTERED);	pcur = node->pcur;	btr_cur = btr_pcur_get_btr_cur(pcur);	ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),					index->table->comp));		/* Try optimistic updating of the record, keeping changes within	the page; we do not check locks because we assume the x-lock on the	record to update */	if (node->cmpl_info & UPD_NODE_NO_SIZE_CHANGE) {		err = btr_cur_update_in_place(BTR_NO_LOCKING_FLAG,						btr_cur, node->update,						node->cmpl_info, thr, mtr);	} else {		err = btr_cur_optimistic_update(BTR_NO_LOCKING_FLAG,						btr_cur, node->update,						node->cmpl_info, thr, mtr);	}	mtr_commit(mtr);		if (err == DB_SUCCESS) {		return(err);	}	if (buf_LRU_buf_pool_running_out()) {			return(DB_LOCK_TABLE_FULL);	}	/* We may have to modify the tree structure: do a pessimistic descent	down the index tree */	mtr_start(mtr);		/* NOTE: this transaction has an s-lock or x-lock on the record and	therefore other transactions cannot modify the record when we have no	latch on the page. In addition, we assume that other query threads of	the same transaction do not modify the record in the meantime.

⌨️ 快捷键说明

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