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

📄 row0ins.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef UNIV_DEBUG	{		page_t*	page = btr_cur_get_page(&cursor);		rec_t*	first_rec = page_rec_get_next(				page_get_infimum_rec(page));		if (UNIV_LIKELY(first_rec != page_get_supremum_rec(page))) {			ut_a(rec_get_n_fields(first_rec, index)			== dtuple_get_n_fields(entry));		}	}#endif	n_unique = dict_index_get_n_unique(index);	if (index->type & DICT_UNIQUE && (cursor.up_match >= n_unique					 || cursor.low_match >= n_unique)) {		if (index->type & DICT_CLUSTERED) {			 			/* Note that the following may return also			DB_LOCK_WAIT */			err = row_ins_duplicate_error_in_clust(&cursor,							entry, thr, &mtr);			if (err != DB_SUCCESS) {				goto function_exit;			}		} else {			mtr_commit(&mtr);			err = row_ins_scan_sec_index_for_duplicate(index,								entry, thr);			mtr_start(&mtr);			if (err != DB_SUCCESS) {				goto function_exit;			}			/* We did not find a duplicate and we have now			locked with s-locks the necessary records to			prevent any insertion of a duplicate by another			transaction. Let us now reposition the cursor and			continue the insertion. */						btr_cur_search_to_nth_level(index, 0, entry,					PAGE_CUR_LE, mode | BTR_INSERT,					&cursor, 0, &mtr);		}			}	modify = row_ins_must_modify(&cursor);	if (modify != 0) {		/* There is already an index entry with a long enough common		prefix, we must convert the insert into a modify of an		existing record */		if (modify == ROW_INS_NEXT) {			rec = page_rec_get_next(btr_cur_get_rec(&cursor));			btr_cur_position(index, rec, &cursor);		}		if (index->type & DICT_CLUSTERED) {			err = row_ins_clust_index_entry_by_modify(mode,							&cursor, &big_rec,							entry,							ext_vec, n_ext_vec,							thr, &mtr);		} else {			err = row_ins_sec_index_entry_by_modify(mode, &cursor,								entry,								thr, &mtr);		}			} else {		if (mode == BTR_MODIFY_LEAF) {			err = btr_cur_optimistic_insert(0, &cursor, entry,					&insert_rec, &big_rec, thr, &mtr);		} else {			ut_a(mode == BTR_MODIFY_TREE);			if (buf_LRU_buf_pool_running_out()) {					err = DB_LOCK_TABLE_FULL;				goto function_exit;			}			err = btr_cur_pessimistic_insert(0, &cursor, entry,					&insert_rec, &big_rec, thr, &mtr);		}		if (err == DB_SUCCESS) {			if (ext_vec) {				rec_set_field_extern_bits(insert_rec, index,						ext_vec, n_ext_vec, &mtr);			}		}	}function_exit:	mtr_commit(&mtr);	if (big_rec) {		rec_t*		rec;		mtr_start(&mtr);			btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,					BTR_MODIFY_TREE, &cursor, 0, &mtr);		rec = btr_cur_get_rec(&cursor);		offsets = rec_get_offsets(rec, index, offsets,					ULINT_UNDEFINED, &heap);		err = btr_store_big_rec_extern_fields(index, rec,						offsets, big_rec, &mtr);		if (modify) {			dtuple_big_rec_free(big_rec);		} else {			dtuple_convert_back_big_rec(index, entry, big_rec);		}		mtr_commit(&mtr);	}	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}	return(err);}/*******************************************************************Inserts an index entry to index. Tries first optimistic, then pessimisticdescent down the tree. If the entry matches enough to a delete marked record,performs the insert by updating or delete unmarking the delete markedrecord. */ulintrow_ins_index_entry(/*================*/				/* out: DB_SUCCESS, DB_LOCK_WAIT,				DB_DUPLICATE_KEY, or some other error code */	dict_index_t*	index,	/* in: index */	dtuple_t*	entry,	/* in: index entry to insert */	ulint*		ext_vec,/* in: array containing field numbers of				externally stored fields in entry, or NULL */	ulint		n_ext_vec,/* in: number of fields in ext_vec */	que_thr_t*	thr)	/* in: query thread */{	ulint	err;	if (UT_LIST_GET_FIRST(index->table->foreign_list)) {		err = row_ins_check_foreign_constraints(index->table, index,								entry, thr);		if (err != DB_SUCCESS) {			return(err);		}	}	/* Try first optimistic descent to the B-tree */	err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry,						ext_vec, n_ext_vec, thr);	if (err != DB_FAIL) {		return(err);	}	/* Try then pessimistic descent to the B-tree */	err = row_ins_index_entry_low(BTR_MODIFY_TREE, index, entry,						ext_vec, n_ext_vec, thr);	return(err);}/***************************************************************Sets the values of the dtuple fields in entry from the values of appropriatecolumns in row. */staticvoidrow_ins_index_entry_set_vals(/*=========================*/	dict_index_t*	index,	/* in: index */	dtuple_t*	entry,	/* in: index entry to make */	dtuple_t*	row)	/* in: row */{	dict_field_t*	ind_field;	dfield_t*	field;	dfield_t*	row_field;	ulint		n_fields;	ulint		i;	dtype_t*        cur_type;	ut_ad(entry && row);	n_fields = dtuple_get_n_fields(entry);	for (i = 0; i < n_fields; i++) {		field = dtuple_get_nth_field(entry, i);		ind_field = dict_index_get_nth_field(index, i);		row_field = dtuple_get_nth_field(row, ind_field->col->ind);		/* Check column prefix indexes */		if (ind_field->prefix_len > 0		    && dfield_get_len(row_field) != UNIV_SQL_NULL) {			cur_type = dict_col_get_type(				dict_field_get_col(ind_field));			field->len = dtype_get_at_most_n_mbchars(cur_type,				  ind_field->prefix_len,				  dfield_get_len(row_field), row_field->data);		} else {		        field->len = row_field->len;		}		field->data = row_field->data;	}}/***************************************************************Inserts a single index entry to the table. */staticulintrow_ins_index_entry_step(/*=====================*/				/* out: DB_SUCCESS if operation successfully				completed, else error code or DB_LOCK_WAIT */	ins_node_t*	node,	/* in: row insert node */	que_thr_t*	thr)	/* in: query thread */{	ulint	err;	ut_ad(dtuple_check_typed(node->row));		row_ins_index_entry_set_vals(node->index, node->entry, node->row);		ut_ad(dtuple_check_typed(node->entry));	err = row_ins_index_entry(node->index, node->entry, NULL, 0, thr);	return(err);}/***************************************************************Allocates a row id for row and inits the node->index field. */UNIV_INLINEvoidrow_ins_alloc_row_id_step(/*======================*/	ins_node_t*	node)	/* in: row insert node */{	dulint	row_id;		ut_ad(node->state == INS_NODE_ALLOC_ROW_ID);		if (dict_table_get_first_index(node->table)->type & DICT_UNIQUE) {		/* No row id is stored if the clustered index is unique */		return;	}		/* Fill in row id value to row */	row_id = dict_sys_get_new_row_id();	dict_sys_write_row_id(node->row_id_buf, row_id);}/***************************************************************Gets a row to insert from the values list. */UNIV_INLINEvoidrow_ins_get_row_from_values(/*========================*/	ins_node_t*	node)	/* in: row insert node */{	que_node_t*	list_node;	dfield_t*	dfield;	dtuple_t*	row;	ulint		i;		/* The field values are copied in the buffers of the select node and	it is safe to use them until we fetch from select again: therefore	we can just copy the pointers */	row = node->row; 	i = 0;	list_node = node->values_list;	while (list_node) {		eval_exp(list_node);		dfield = dtuple_get_nth_field(row, i);		dfield_copy_data(dfield, que_node_get_val(list_node));		i++;		list_node = que_node_get_next(list_node);	}}/***************************************************************Gets a row to insert from the select list. */UNIV_INLINEvoidrow_ins_get_row_from_select(/*========================*/	ins_node_t*	node)	/* in: row insert node */{	que_node_t*	list_node;	dfield_t*	dfield;	dtuple_t*	row;	ulint		i;	/* The field values are copied in the buffers of the select node and	it is safe to use them until we fetch from select again: therefore	we can just copy the pointers */	row = node->row; 	i = 0;	list_node = node->select->select_list;	while (list_node) {		dfield = dtuple_get_nth_field(row, i);		dfield_copy_data(dfield, que_node_get_val(list_node));		i++;		list_node = que_node_get_next(list_node);	}}	/***************************************************************Inserts a row to a table. */ulintrow_ins(/*====*/				/* out: DB_SUCCESS if operation successfully				completed, else error code or DB_LOCK_WAIT */	ins_node_t*	node,	/* in: row insert node */	que_thr_t*	thr)	/* in: query thread */{	ulint	err;		ut_ad(node && thr);	if (node->state == INS_NODE_ALLOC_ROW_ID) {		row_ins_alloc_row_id_step(node);			node->index = dict_table_get_first_index(node->table);		node->entry = UT_LIST_GET_FIRST(node->entry_list);		if (node->ins_type == INS_SEARCHED) {			row_ins_get_row_from_select(node);		} else if (node->ins_type == INS_VALUES) {			row_ins_get_row_from_values(node);		}		node->state = INS_NODE_INSERT_ENTRIES;	}	ut_ad(node->state == INS_NODE_INSERT_ENTRIES);	while (node->index != NULL) {		err = row_ins_index_entry_step(node, thr);				if (err != DB_SUCCESS) {			return(err);		}		node->index = dict_table_get_next_index(node->index);		node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);	}	ut_ad(node->entry == NULL);		node->state = INS_NODE_ALLOC_ROW_ID;		return(DB_SUCCESS);}/***************************************************************Inserts a row to a table. This is a high-level function used in SQL executiongraphs. */que_thr_t*row_ins_step(/*=========*/				/* out: query thread to run next or NULL */	que_thr_t*	thr)	/* in: query thread */{	ins_node_t*	node;	que_node_t*	parent;	sel_node_t*	sel_node;	trx_t*		trx;	ulint		err;	ut_ad(thr);		trx = thr_get_trx(thr);	trx_start_if_not_started(trx);		node = thr->run_node;	ut_ad(que_node_get_type(node) == QUE_NODE_INSERT);	parent = que_node_get_parent(node);	sel_node = node->select;	if (thr->prev_node == parent) {		node->state = INS_NODE_SET_IX_LOCK;	}	/* If this is the first time this node is executed (or when	execution resumes after wait for the table IX lock), set an	IX lock on the table and reset the possible select node. */	if (node->state == INS_NODE_SET_IX_LOCK) {		/* It may be that the current session has not yet started		its transaction, or it has been committed: */				if (UT_DULINT_EQ(trx->id, node->trx_id)) {			/* No need to do IX-locking or write trx id to buf */			goto same_trx;		}			trx_write_trx_id(node->trx_id_buf, trx->id);		err = lock_table(0, node->table, LOCK_IX, thr);		if (err != DB_SUCCESS) {			goto error_handling;		}		node->trx_id = trx->id;	same_trx:						node->state = INS_NODE_ALLOC_ROW_ID;		if (node->ins_type == INS_SEARCHED) {			/* Reset the cursor */			sel_node->state = SEL_NODE_OPEN; 					/* Fetch a row to insert */					thr->run_node = sel_node;				return(thr);		}	}	if ((node->ins_type == INS_SEARCHED)				&& (sel_node->state != SEL_NODE_FETCH)) {		ut_ad(sel_node->state == SEL_NODE_NO_MORE_ROWS);		/* No more rows to insert */		thr->run_node = parent;			return(thr);	}	/* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */	err = row_ins(node, thr);error_handling:	trx->error_state = err;	if (err != DB_SUCCESS) {		/* err == DB_LOCK_WAIT or SQL error detected */		return(NULL);	}	/* DO THE TRIGGER ACTIONS HERE */	if (node->ins_type == INS_SEARCHED) {		/* Fetch a row to insert */				thr->run_node = sel_node;	} else {		thr->run_node = que_node_get_parent(node);	}	return(thr);}

⌨️ 快捷键说明

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