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

📄 dict0dict.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	return(FALSE);}/*************************************************************************Frees a foreign key struct. */staticvoiddict_foreign_free(/*==============*/	dict_foreign_t*	foreign)	/* in, own: foreign key struct */{	mem_heap_free(foreign->heap);}/**************************************************************************Removes a foreign constraint struct from the dictionary cache. */staticvoiddict_foreign_remove_from_cache(/*===========================*/	dict_foreign_t*	foreign)	/* in, own: foreign constraint */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	ut_a(foreign);		if (foreign->referenced_table) {		UT_LIST_REMOVE(referenced_list,			foreign->referenced_table->referenced_list, foreign);	}	if (foreign->foreign_table) {		UT_LIST_REMOVE(foreign_list,			foreign->foreign_table->foreign_list, foreign);	}	dict_foreign_free(foreign);}/**************************************************************************Looks for the foreign constraint from the foreign and referenced listsof a table. */staticdict_foreign_t*dict_foreign_find(/*==============*/				/* out: foreign constraint */	dict_table_t*	table,	/* in: table object */	const char*	id)	/* in: foreign constraint id */{	dict_foreign_t*	foreign;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	foreign = UT_LIST_GET_FIRST(table->foreign_list);	while (foreign) {		if (ut_strcmp(id, foreign->id) == 0) {			return(foreign);		}		foreign = UT_LIST_GET_NEXT(foreign_list, foreign);	}		foreign = UT_LIST_GET_FIRST(table->referenced_list);	while (foreign) {		if (ut_strcmp(id, foreign->id) == 0) {			return(foreign);		}		foreign = UT_LIST_GET_NEXT(referenced_list, foreign);	}	return(NULL);}	/*************************************************************************Tries to find an index whose first fields are the columns in the array,in the same order. */staticdict_index_t*dict_foreign_find_index(/*====================*/				/* out: matching index, NULL if not found */	dict_table_t*	table,	/* in: table */	const char**	columns,/* in: array of column names */	ulint		n_cols,	/* in: number of columns */	dict_index_t*	types_idx, /* in: NULL or an index to whose types the				   column types must match */	ibool		check_charsets)	/* in: whether to check charsets.					only has an effect if types_idx !=					NULL. */{#ifndef UNIV_HOTBACKUP	dict_index_t*	index;	const char*	col_name;	ulint		i;		index = dict_table_get_first_index(table);	while (index != NULL) {		if (dict_index_get_n_fields(index) >= n_cols) {			for (i = 0; i < n_cols; i++) {				col_name = dict_index_get_nth_field(index, i)							->col->name;				if (dict_index_get_nth_field(index, i)						->prefix_len != 0) {					/* We do not accept column prefix					indexes here */										break;				}				if (0 != innobase_strcasecmp(columns[i],								col_name)) {				  	break;				}				if (types_idx && !cmp_types_are_equal(				     dict_index_get_nth_type(index, i),				     dict_index_get_nth_type(types_idx, i),				     check_charsets)) {				  	break;				}					}			if (i == n_cols) {				/* We found a matching index */				return(index);			}		}		index = dict_table_get_next_index(index);	}	return(NULL);#else /* UNIV_HOTBACKUP */	/* This function depends on MySQL code that is not included in	InnoDB Hot Backup builds.  Besides, this function should never	be called in InnoDB Hot Backup. */	ut_error;#endif /* UNIV_HOTBACKUP */}/**************************************************************************Report an error in a foreign key definition. */staticvoiddict_foreign_error_report_low(/*==========================*/	FILE*		file,	/* in: output stream */	const char*	name)	/* in: table name */{	rewind(file);	ut_print_timestamp(file);	fprintf(file, " Error in foreign key constraint of table %s:\n",		name);}/**************************************************************************Report an error in a foreign key definition. */staticvoiddict_foreign_error_report(/*======================*/	FILE*		file,	/* in: output stream */	dict_foreign_t*	fk,	/* in: foreign key constraint */	const char*	msg)	/* in: the error message */{	mutex_enter(&dict_foreign_err_mutex);	dict_foreign_error_report_low(file, fk->foreign_table_name);	fputs(msg, file);	fputs(" Constraint:\n", file);	dict_print_info_on_foreign_key_in_create_format(file, NULL, fk, TRUE);	putc('\n', file);	if (fk->foreign_index) {		fputs("The index in the foreign key in table is ", file);		ut_print_name(file, NULL, fk->foreign_index->name);		fputs("\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n""for correct foreign key definition.\n",		file);	}	mutex_exit(&dict_foreign_err_mutex);}/**************************************************************************Adds a foreign key constraint object to the dictionary cache. May freethe object if there already is an object with the same identifier in.At least one of the foreign table and the referenced table must alreadybe in the dictionary cache! */ulintdict_foreign_add_to_cache(/*======================*/					/* out: DB_SUCCESS or error code */	dict_foreign_t*	foreign,	/* in, own: foreign key constraint */	ibool		check_charsets)	/* in: TRUE=check charset					compatibility */{	dict_table_t*	for_table;	dict_table_t*	ref_table;	dict_foreign_t*	for_in_cache		= NULL;	dict_index_t*	index;	ibool		added_to_referenced_list= FALSE;	FILE*		ef 			= dict_foreign_err_file;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	for_table = dict_table_check_if_in_cache_low(					foreign->foreign_table_name);		ref_table = dict_table_check_if_in_cache_low(					foreign->referenced_table_name);	ut_a(for_table || ref_table);	if (for_table) {		for_in_cache = dict_foreign_find(for_table, foreign->id);	}	if (!for_in_cache && ref_table) {		for_in_cache = dict_foreign_find(ref_table, foreign->id);	}	if (for_in_cache) {		/* Free the foreign object */		mem_heap_free(foreign->heap);	} else {		for_in_cache = foreign;	}	if (for_in_cache->referenced_table == NULL && ref_table) {		index = dict_foreign_find_index(ref_table,			(const char**) for_in_cache->referenced_col_names,			for_in_cache->n_fields,			for_in_cache->foreign_index, check_charsets);		if (index == NULL) {			dict_foreign_error_report(ef, for_in_cache,"there is no index in referenced table which would contain\n""the columns as the first columns, or the data types in the\n""referenced table do not match to the ones in table.");			if (for_in_cache == foreign) {				mem_heap_free(foreign->heap);			}		    	return(DB_CANNOT_ADD_CONSTRAINT);		}		for_in_cache->referenced_table = ref_table;		for_in_cache->referenced_index = index;		UT_LIST_ADD_LAST(referenced_list,					ref_table->referenced_list,					for_in_cache);		added_to_referenced_list = TRUE;	}	if (for_in_cache->foreign_table == NULL && for_table) {		index = dict_foreign_find_index(for_table,			(const char**) for_in_cache->foreign_col_names,			for_in_cache->n_fields,			for_in_cache->referenced_index, check_charsets);		if (index == NULL) {			dict_foreign_error_report(ef, for_in_cache,"there is no index in the table which would contain\n""the columns as the first columns, or the data types in the\n""table do not match to the ones in the referenced table.");			if (for_in_cache == foreign) {				if (added_to_referenced_list) {					UT_LIST_REMOVE(referenced_list,						ref_table->referenced_list,						for_in_cache);				}							mem_heap_free(foreign->heap);			}		    	return(DB_CANNOT_ADD_CONSTRAINT);		}		for_in_cache->foreign_table = for_table;		for_in_cache->foreign_index = index;		UT_LIST_ADD_LAST(foreign_list,					for_table->foreign_list,					for_in_cache);	}	return(DB_SUCCESS);}/*************************************************************************Scans from pointer onwards. Stops if is at the start of a copy of'string' where characters are compared without case sensitivity, andonly outside `` or "" quotes. Stops also at '\0'. */const char*dict_scan_to(/*=========*/				/* out: scanned up to this */	const char*	ptr,	/* in: scan from */	const char*	string)	/* in: look for this */{	char	quote	= '\0';	for (; *ptr; ptr++) {		if (*ptr == quote) {			/* Closing quote character: do not look for			starting quote or the keyword. */			quote = '\0';		} else if (quote) {			/* Within quotes: do nothing. */		} else if (*ptr == '`' || *ptr == '"') {			/* Starting quote: remember the quote character. */			quote = *ptr;		} else {			/* Outside quotes: look for the keyword. */			ulint	i;			for (i = 0; string[i]; i++) {				if (toupper((int)(unsigned char)(ptr[i]))						!= toupper((int)(unsigned char)						(string[i]))) {					goto nomatch;				}			}			break;		nomatch:			;		}	}	return(ptr);}/*************************************************************************Accepts a specified string. Comparisons are case-insensitive. */const char*dict_accept(/*========*/				/* out: if string was accepted, the pointer				is moved after that, else ptr is returned */	const char*	ptr,	/* in: scan from this */	const char*	string,	/* in: accept only this string as the next				non-whitespace string */	ibool*		success)/* out: TRUE if accepted */{	const char*	old_ptr = ptr;	const char*	old_ptr2;	*success = FALSE;		while (isspace(*ptr)) {		ptr++;	}	old_ptr2 = ptr;		ptr = dict_scan_to(ptr, string);		if (*ptr == '\0' || old_ptr2 != ptr) {		return(old_ptr);	}	*success = TRUE;	return(ptr + ut_strlen(string));}/*************************************************************************Scans an id. For the lexical definition of an 'id', see the code below.Strips backquotes or double quotes from around the id. */staticconst char*dict_scan_id(/*=========*/				/* out: scanned to */	const char*	ptr,	/* in: scanned to */	mem_heap_t*	heap,	/* in: heap where to allocate the id				(NULL=id will not be allocated, but it				will point to string near ptr) */	const char**	id,	/* out,own: the id; NULL if no id was				scannable */	ibool		accept_also_dot)				/* in: TRUE if also a dot can appear in a				non-quoted id; in a quoted id it can appear				always */{	char		quote	= '\0';	ulint		len	= 0;	const char*	s;	char*		d;	ulint		id_len;	byte*		b;	*id = NULL;	while (isspace(*ptr)) {		ptr++;	}	if (*ptr == '\0') {		return(ptr);	}	if (*ptr == '`' || *ptr == '"') {		quote = *ptr++;	}	s = ptr;	if (quote) {		for (;;) {			if (!*ptr) {				/* Syntax error */				return(ptr);			}			if (*ptr == quote) {				ptr++;				if (*ptr != quote) {					break;				}			}			ptr++;			len++;		}	} else {		while (!isspace(*ptr) && *ptr != '(' && *ptr != ')'		       && (accept_also_dot || *ptr != '.')		       && *ptr != ',' && *ptr != '\0') {			ptr++;		}		len = ptr - s;	}	if (quote && heap) {		*id = d = mem_heap_alloc(heap, len + 1);		while (len--) {			if ((*d++ = *s++) == quote) {				s++;			}		}		*d++ = 0;		ut_a(*s == quote);		ut_a(s + 1 == ptr);	} else if (heap) {		*id = mem_heap_strdupl(heap, s, len);	} else {		/* no heap given: id will point to source string */		*id = s;	}	if (heap && !quote) {		/* EMS MySQL Manager sometimes adds characters 0xA0 (in		latin1, a 'non-breakable space') to the end of a table name.		But isspace(0xA0) is not true, which confuses our foreign key		parser. After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2		and 0xA0 are at the end of the string.		TODO: we should lex the string using thd->charset_info, and		my_isspace(). Only after that, convert id names to UTF-8. */		b = (byte*)(*id);		id_len = strlen((char*) b);				if (id_len >= 3 && b[id_len - 1] == 0xA0			       && b[id_len - 2] == 0xC2) {			/* Strip the 2 last bytes */			b[id_len - 2] = '\0';		}	}	return(ptr);}/*************************************************************************Tries to scan a column name. */staticconst char*dict_scan_col(/*==========*/				/* out: scanned to */	const char*	ptr,	/* in: scanned t

⌨️ 快捷键说明

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