Commit a1da992f authored by unknown's avatar unknown
Browse files

Merge marko@bk-internal.mysql.com:/home/bk/mysql-5.0

into hundin.mysql.fi:/home/marko/mysql-5.0-current


sql/ha_innodb.cc:
  Auto merged
parents 5d82b41e da838339
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -316,7 +316,9 @@ btr_cur_search_to_nth_level(
	if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED
		&& latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ
		&& !estimate
#ifdef PAGE_CUR_LE_OR_EXTENDS
		&& mode != PAGE_CUR_LE_OR_EXTENDS
#endif /* PAGE_CUR_LE_OR_EXTENDS */
		&& srv_use_adaptive_hash_indexes
	        && btr_search_guess_on_hash(index, info, tuple, mode,
						latch_mode, cursor,
@@ -391,8 +393,10 @@ btr_cur_search_to_nth_level(
		break;
	default:
		ut_ad(mode == PAGE_CUR_L
			|| mode == PAGE_CUR_LE
			|| mode == PAGE_CUR_LE_OR_EXTENDS);
#ifdef PAGE_CUR_LE_OR_EXTENDS
			|| mode == PAGE_CUR_LE_OR_EXTENDS
#endif /* PAGE_CUR_LE_OR_EXTENDS */
			|| mode == PAGE_CUR_LE);
		page_mode = mode;
		break;
	}
+4 −2
Original line number Diff line number Diff line
@@ -26,11 +26,13 @@ Created 10/4/1994 Heikki Tuuri
#define	PAGE_CUR_GE	2
#define	PAGE_CUR_L	3
#define	PAGE_CUR_LE	4
#define PAGE_CUR_LE_OR_EXTENDS 5 /* This is a search mode used in
/*#define PAGE_CUR_LE_OR_EXTENDS 5*/ /* This is a search mode used in
				 "column LIKE 'abc%' ORDER BY column DESC";
				 we have to find strings which are <= 'abc' or
				 which extend it */
#define	PAGE_CUR_DBG	6
#ifdef UNIV_SEARCH_DEBUG
# define PAGE_CUR_DBG	6	/* As PAGE_CUR_LE, but skips search shortcut */
#endif /* UNIV_SEARCH_DEBUG */

#ifdef PAGE_CUR_ADAPT
# ifdef UNIV_SEARCH_PERF_STAT
+56 −44
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ page_cur_try_search_shortcut(
				not yet completely matched */
	page_cur_t*	cursor) /* out: page cursor */ 
{
	int	cmp;
	rec_t*	rec;
	rec_t*	next_rec;
	ulint	low_match;
@@ -79,9 +78,8 @@ page_cur_try_search_shortcut(
	up_match = low_match;
	up_bytes = low_bytes;

	cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match,
								&low_bytes);
	if (cmp == -1) {
	if (page_cmp_dtuple_rec_with_match(tuple, rec, offsets,
						&low_match, &low_bytes) < 0) {
		goto exit_func;
	}

@@ -89,9 +87,8 @@ page_cur_try_search_shortcut(
	offsets = rec_get_offsets(next_rec, index, offsets,
				dtuple_get_n_fields(tuple), &heap);

	cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
						&up_match, &up_bytes);
	if (cmp != -1) {
	if (page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
						&up_match, &up_bytes) >= 0) {
		goto exit_func;
	}

@@ -115,7 +112,7 @@ page_cur_try_search_shortcut(
	ut_a(*ilow_matched_fields == low_match);
	ut_a(*ilow_matched_bytes == low_bytes);
#endif
	if (next_rec != page_get_supremum_rec(page)) {
	if (!page_rec_is_supremum(next_rec)) {

		*iup_matched_fields = up_match;
		*iup_matched_bytes = up_bytes;
@@ -137,6 +134,7 @@ page_cur_try_search_shortcut(

#endif

#ifdef PAGE_CUR_LE_OR_EXTENDS
/********************************************************************
Checks if the nth field in a record is a character type field which extends
the nth field in tuple, i.e., the field is longer or equal in length and has
@@ -185,6 +183,7 @@ page_cur_rec_field_extends(

        return(FALSE);
}
#endif /* PAGE_CUR_LE_OR_EXTENDS */

/********************************************************************
Searches the right position for a page cursor. */
@@ -240,8 +239,13 @@ page_cur_search_with_match(
	ut_ad(dtuple_validate(tuple));
	ut_ad(dtuple_check_typed(tuple));
	ut_ad((mode == PAGE_CUR_L) || (mode == PAGE_CUR_LE)
	      || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)
	      || (mode == PAGE_CUR_LE_OR_EXTENDS) || (mode == PAGE_CUR_DBG));
#ifdef PAGE_CUR_DBG
	      || (mode == PAGE_CUR_DBG)
#endif /* PAGE_CUR_DBG */
#ifdef PAGE_CUR_LE_OR_EXTENDS
	      || (mode == PAGE_CUR_LE_OR_EXTENDS)
#endif /* PAGE_CUR_LE_OR_EXTENDS */
	      || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE));

	page_check_dir(page);

@@ -261,16 +265,18 @@ page_cur_search_with_match(
	    		return;
	    	}
	}
/*#ifdef UNIV_SEARCH_DEBUG */
# ifdef PAGE_CUR_DBG
	if (mode == PAGE_CUR_DBG) {
		mode = PAGE_CUR_LE;
	}
/*#endif */
# endif
#endif	

	/* The following flag does not work for non-latin1 char sets because
	cmp_full_field does not tell how many bytes matched */
#ifdef PAGE_CUR_LE_OR_EXTENDS
	ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); 
#endif /* PAGE_CUR_LE_OR_EXTENDS */

	/* If mode PAGE_CUR_G is specified, we are trying to position the
	cursor to answer a query of the form "tuple < X", where tuple is
@@ -308,33 +314,36 @@ page_cur_search_with_match(
		cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
						&cur_matched_fields,
						&cur_matched_bytes);
		if (cmp == 1) {
		if (UNIV_LIKELY(cmp > 0)) {
low_slot_match:
			low = mid;
			low_matched_fields = cur_matched_fields;
			low_matched_bytes = cur_matched_bytes;

		} else if (cmp == -1) {
		} else if (UNIV_LIKELY(cmp /* == -1 */)) {
#ifdef PAGE_CUR_LE_OR_EXTENDS
			if (mode == PAGE_CUR_LE_OR_EXTENDS
			    && page_cur_rec_field_extends(tuple, mid_rec,
						offsets, cur_matched_fields)) {
				low = mid;
				low_matched_fields = cur_matched_fields;
				low_matched_bytes = cur_matched_bytes;
			} else {

				goto low_slot_match;
			}
#endif /* PAGE_CUR_LE_OR_EXTENDS */
up_slot_match:
			up = mid;
			up_matched_fields = cur_matched_fields;
			up_matched_bytes = cur_matched_bytes;
			}

		} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
			   || mode == PAGE_CUR_LE_OR_EXTENDS) {
			low = mid;
			low_matched_fields = cur_matched_fields;
			low_matched_bytes = cur_matched_bytes;
#ifdef PAGE_CUR_LE_OR_EXTENDS
			   || mode == PAGE_CUR_LE_OR_EXTENDS
#endif /* PAGE_CUR_LE_OR_EXTENDS */
		) {

			goto low_slot_match;
		} else {
			up = mid;
			up_matched_fields = cur_matched_fields;
			up_matched_bytes = cur_matched_bytes;

			goto up_slot_match;
		}
   	}

@@ -360,32 +369,35 @@ page_cur_search_with_match(
		cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
						&cur_matched_fields,
						&cur_matched_bytes);
		if (cmp == 1) {
		if (UNIV_LIKELY(cmp > 0)) {
low_rec_match:
			low_rec = mid_rec;
			low_matched_fields = cur_matched_fields;
			low_matched_bytes = cur_matched_bytes;

		} else if (cmp == -1) {
		} else if (UNIV_LIKELY(cmp /* == -1 */)) {
#ifdef PAGE_CUR_LE_OR_EXTENDS
			if (mode == PAGE_CUR_LE_OR_EXTENDS
			    && page_cur_rec_field_extends(tuple, mid_rec,
						offsets, cur_matched_fields)) {
				low_rec = mid_rec;
				low_matched_fields = cur_matched_fields;
				low_matched_bytes = cur_matched_bytes;
			} else {

				goto low_rec_match;
			}
#endif /* PAGE_CUR_LE_OR_EXTENDS */
up_rec_match:
			up_rec = mid_rec;
			up_matched_fields = cur_matched_fields;
			up_matched_bytes = cur_matched_bytes;
			}
		} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
			   || mode == PAGE_CUR_LE_OR_EXTENDS) {
			low_rec = mid_rec;
			low_matched_fields = cur_matched_fields;
			low_matched_bytes = cur_matched_bytes;
#ifdef PAGE_CUR_LE_OR_EXTENDS
			   || mode == PAGE_CUR_LE_OR_EXTENDS
#endif /* PAGE_CUR_LE_OR_EXTENDS */
		) {

			goto low_rec_match;
		} else {
			up_rec = mid_rec;
			up_matched_fields = cur_matched_fields;
			up_matched_bytes = cur_matched_bytes;

			goto up_rec_match;
		}
   	}

+67 −38
Original line number Diff line number Diff line
@@ -601,30 +601,38 @@ rec_set_nth_field_extern_bit_new(

	/* read the lengths of fields 0..n */
	for (i = 0; i < n_fields; i++) {
		ibool	is_null;
		ulint	len;
		field = dict_index_get_nth_field(index, i);
		type = dict_col_get_type(dict_field_get_col(field));
		is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL);
		if (is_null) {
			/* nullable field => read the null flag */
			is_null = !!(*nulls & null_mask);
		if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
			if (UNIV_UNLIKELY(!(byte) null_mask)) {
				nulls--;
				null_mask = 1;
			}

			if (*nulls & null_mask) {
				null_mask <<= 1;
			if (null_mask == 0x100)
				nulls--, null_mask = 1;
				/* NULL fields cannot be external. */
				ut_ad(i != ith);
				continue;
			}
		if (is_null || field->fixed_len) {
			/* No length (or extern bit) is stored for
			fields that are NULL or fixed-length. */

			null_mask <<= 1;
		}
		if (field->fixed_len) {
			/* fixed-length fields cannot be external
			(Fixed-length fields longer than
			DICT_MAX_COL_PREFIX_LEN will be treated as
			variable-length ones in dict_index_add_col().) */
			ut_ad(i != ith);
			continue;
		}
		len = *lens--;
		lens--;
		if (dtype_get_len(type) > 255
				|| dtype_get_mtype(type) == DATA_BLOB) {
			ulint	len = lens[1];
			if (len & 0x80) { /* 1exxxxxx: 2-byte length */
				if (i == ith) {
					if (!val == !(len & 0x20)) {
					if (!val == !(len & 0x40)) {
						return; /* no change */
					}
					/* toggle the extern bit */
@@ -823,6 +831,7 @@ rec_convert_dtuple_to_rec_new(
	byte*		lens;
	ulint		len;
	ulint		i;
	ulint		n_node_ptr_field;
	ulint		fixed_len;
	ulint		null_mask	= 1;
	const ulint	n_fields	= dtuple_get_n_fields(dtuple);
@@ -831,16 +840,26 @@ rec_convert_dtuple_to_rec_new(
	ut_ad(index->table->comp);

	ut_ad(n_fields > 0);
	switch (status) {

	/* Try to ensure that the memset() between the for() loops
	completes fast.  The address is not exact, but UNIV_PREFETCH
	should never generate a memory fault. */
	UNIV_PREFETCH_RW(rec - REC_N_NEW_EXTRA_BYTES - n_fields);
	UNIV_PREFETCH_RW(rec);

	switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
	case REC_STATUS_ORDINARY:
		ut_ad(n_fields <= dict_index_get_n_fields(index));
		n_node_ptr_field = ULINT_UNDEFINED;
		break;
	case REC_STATUS_NODE_PTR:
		ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1);
		n_node_ptr_field = n_fields - 1;
		break;
	case REC_STATUS_INFIMUM:
	case REC_STATUS_SUPREMUM:
		ut_ad(n_fields == 1);
		n_node_ptr_field = ULINT_UNDEFINED;
		goto init;
	default:
		ut_a(0);
@@ -852,15 +871,18 @@ rec_convert_dtuple_to_rec_new(
	rec += (index->n_nullable + 7) / 8;

	for (i = 0; i < n_fields; i++) {
		if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
#ifdef UNIV_DEBUG
			field = dtuple_get_nth_field(dtuple, i);
			type = dfield_get_type(field);
		len = dfield_get_len(field);
		if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) {
			fixed_len = 4;
			ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
			ut_ad(len == 4);
			continue;
			ut_ad(dfield_get_len(field) == 4);
#endif /* UNIV_DEBUG */
			goto init;
		}
		field = dtuple_get_nth_field(dtuple, i);
		type = dfield_get_type(field);
		len = dfield_get_len(field);
		fixed_len = dict_index_get_nth_field(index, i)->fixed_len;

		if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
@@ -902,28 +924,34 @@ rec_convert_dtuple_to_rec_new(
		type = dfield_get_type(field);
		len = dfield_get_len(field);

		if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) {
			fixed_len = 4;
		if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
			ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL);
			ut_ad(len == 4);
			goto copy;
			memcpy(end, dfield_get_data(field), len);
			break;
		}
		fixed_len = dict_index_get_nth_field(index, i)->fixed_len;

		if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
			/* nullable field */
			ut_ad(index->n_nullable > 0);

			if (UNIV_UNLIKELY(!(byte) null_mask)) {
				nulls--;
				null_mask = 1;
			}

			ut_ad(*nulls < null_mask);

			/* set the null flag if necessary */
			if (len == UNIV_SQL_NULL) {
				*nulls |= null_mask;
			}
				null_mask <<= 1;
			if (null_mask == 0x100)
				nulls--, null_mask = 1;
			if (len == UNIV_SQL_NULL)
				continue;
			}

			null_mask <<= 1;
		}
		/* only nullable fields can be null */
		ut_ad(len != UNIV_SQL_NULL);
		if (fixed_len) {
@@ -942,7 +970,7 @@ rec_convert_dtuple_to_rec_new(
				*lens-- = (byte) len;
			}
		}
	copy:

		memcpy(end, dfield_get_data(field), len);
		end += len;
	}
@@ -1105,7 +1133,6 @@ rec_copy_prefix_to_buf(
	dtype_t*	type;
	ulint		i;
	ulint		prefix_len;
	ibool		is_null;
	ulint		null_mask;
	ulint		status;

@@ -1146,20 +1173,22 @@ rec_copy_prefix_to_buf(
	for (i = 0; i < n_fields; i++) {
		field = dict_index_get_nth_field(index, i);
		type = dict_col_get_type(dict_field_get_col(field));
		is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL);
		if (is_null) {
		if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
			/* nullable field => read the null flag */
			is_null = !!(*nulls & null_mask);
			null_mask <<= 1;
			if (null_mask == 0x100) {
				--nulls;
				UNIV_PREFETCH_R(nulls);
			if (UNIV_UNLIKELY(!(byte) null_mask)) {
				nulls--;
				null_mask = 1;
			}

			if (*nulls & null_mask) {
				null_mask <<= 1;
				continue;
			}

			null_mask <<= 1;
		}

		if (is_null) {
		} else if (field->fixed_len) {
		if (field->fixed_len) {
			prefix_len += field->fixed_len;
		} else {
			ulint	len = *lens--;
+32 −9
Original line number Diff line number Diff line
@@ -2955,21 +2955,44 @@ build_template(
		templ = prebuilt->mysql_template + n_requested_fields;
		field = table->field[i];

                ibool index_contains_field=
		if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
			/* Decide which columns we should fetch
			and which we can skip. */
			register const ibool	index_contains_field =
				dict_index_contains_col_or_prefix(index, i);

		if (templ_type == ROW_MYSQL_REC_FIELDS && 
                    ((prebuilt->read_just_key && !index_contains_field) ||
		     (!(fetch_all_in_key && index_contains_field) &&
		      !(fetch_primary_key_cols &&
			dict_table_col_in_clustered_key(index->table, i)) &&
		      thd->query_id != field->query_id))) {
			if (!index_contains_field && prebuilt->read_just_key) {
				/* If this is a 'key read', we do not need
				columns that are not in the key */

				goto skip_field;
			}

			if (index_contains_field && fetch_all_in_key) {
				/* This field is needed in the query */

				goto include_field;
			}

			if (thd->query_id == field->query_id) {
				/* This field is needed in the query */

				goto include_field;
			}

			if (fetch_primary_key_cols
			    && dict_table_col_in_clustered_key(index->table,
									i)) {
				/* This field is needed in the query */

				goto include_field;
			}

			/* This field is not needed in the query, skip it */

			goto skip_field;
		}

include_field:
		n_requested_fields++;

		templ->col_no = i;