Commit a2d94d92 authored by unknown's avatar unknown
Browse files

dict0dict.h, dict0dict.c, row0row.c, pars0opt.c:

  Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref()


innobase/pars/pars0opt.c:
  Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref()
innobase/row/row0row.c:
  Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref()
innobase/dict/dict0dict.c:
  Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref()
innobase/include/dict0dict.h:
  Fix bug #5180: having a column prefix index in the primary key, and the same column fully in a secondary key could cause an assertion failure in row_build_row_ref()
parent 8bf8c859
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -526,8 +526,10 @@ dict_index_contains_col_or_prefix(
}

/************************************************************************
Looks for a matching field in an index. The column and the prefix len have
to be the same. */
Looks for a matching field in an index. The column has to be the same. The
column in index must be complete, or must contain a prefix longer than the
column in index2. That is, we must be able to construct the prefix in index2
from the prefix in index. */

ulint
dict_index_get_nth_field_pos(
@@ -555,7 +557,9 @@ dict_index_get_nth_field_pos(
		field = dict_index_get_nth_field(index, pos);

		if (field->col == field2->col
		    && field->prefix_len == field2->prefix_len) {
		    && (field->prefix_len == 0
			|| (field->prefix_len >= field2->prefix_len
			    && field2->prefix_len != 0))) {

			return(pos);
		}
+4 −2
Original line number Diff line number Diff line
@@ -566,8 +566,10 @@ dict_index_contains_col_or_prefix(
	dict_index_t*	index,	/* in: index */
	ulint		n);	/* in: column number */
/************************************************************************
Looks for a matching field in an index. The column and the prefix len has
to be the same. */
Looks for a matching field in an index. The column has to be the same. The
column in index must be complete, or must contain a prefix longer than the
column in index2. That is, we must be able to construct the prefix in index2
from the prefix in index. */

ulint
dict_index_get_nth_field_pos(
+13 −0
Original line number Diff line number Diff line
@@ -1094,6 +1094,19 @@ opt_clust_access(
	for (i = 0; i < n_fields; i++) {
		pos = dict_index_get_nth_field_pos(index, clust_index, i);

		ut_a(pos != ULINT_UNDEFINED);

		/* We optimize here only queries to InnoDB's internal system
		tables, and they should not contain column prefix indexes. */

		if (dict_index_get_nth_field(index, pos)->prefix_len != 0
		    || dict_index_get_nth_field(clust_index, i)
							->prefix_len != 0) {
			fprintf(stderr,
"InnoDB: Error in pars0opt.c: table %s has prefix_len != 0\n",
				index->table_name);
		}

		*(plan->clust_map + i) = pos;

		ut_ad((pos != ULINT_UNDEFINED)
+34 −0
Original line number Diff line number Diff line
@@ -334,6 +334,7 @@ row_build_row_ref(
	ulint		ref_len;
	ulint		pos;
	byte*		buf;
	ulint		clust_col_prefix_len;
	ulint		i;
	
	ut_ad(index && rec && heap);
@@ -366,6 +367,22 @@ row_build_row_ref(
		field = rec_get_nth_field(rec, pos, &len);

		dfield_set_data(dfield, field, len);

		/* If the primary key contains a column prefix, then the
		secondary index may contain a longer prefix of the same
		column, or the full column, and we must adjust the length
		accordingly. */

		clust_col_prefix_len =
			dict_index_get_nth_field(clust_index, i)->prefix_len;

		if (clust_col_prefix_len > 0) {
		    	if (len != UNIV_SQL_NULL
			    && len > clust_col_prefix_len) {

				dfield_set_len(dfield, clust_col_prefix_len);
			}
		}
	}

	ut_ad(dtuple_check_typed(ref));
@@ -396,6 +413,7 @@ row_build_row_ref_in_tuple(
	ulint		len;
	ulint		ref_len;
	ulint		pos;
	ulint		clust_col_prefix_len;
	ulint		i;
	
	ut_a(ref && index && rec);
@@ -433,6 +451,22 @@ row_build_row_ref_in_tuple(
		field = rec_get_nth_field(rec, pos, &len);

		dfield_set_data(dfield, field, len);

		/* If the primary key contains a column prefix, then the
		secondary index may contain a longer prefix of the same
		column, or the full column, and we must adjust the length
		accordingly. */

		clust_col_prefix_len =
			dict_index_get_nth_field(clust_index, i)->prefix_len;

		if (clust_col_prefix_len > 0) {
		    	if (len != UNIV_SQL_NULL
			    && len > clust_col_prefix_len) {

				dfield_set_len(dfield, clust_col_prefix_len);
			}
		}
	}

	ut_ad(dtuple_check_typed(ref));