Commit 32118765 authored by unknown's avatar unknown
Browse files

Merge jlindstrom@build.mysql.com:/home/bk/mysql-4.1

into hundin.mysql.fi:/home/jan/mysql-4.1


mysql-test/r/ctype_utf8.result:
  Auto merged
mysql-test/t/ctype_utf8.test:
  Auto merged
parents 29c44aa9 3ddb80a7
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -2401,13 +2401,16 @@ btr_index_rec_validate(

		rec_get_nth_field(rec, i, &len);

		/* Note that prefix indexes are not fixed size even when
		their type is CHAR. */

		if ((dict_index_get_nth_field(index, i)->prefix_len == 0
		    && len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
		    && len != dtype_get_fixed_size(type))
		   ||
		   (dict_index_get_nth_field(index, i)->prefix_len > 0
		    && len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
		    && len !=
		    && len != UNIV_SQL_NULL
		    && len >
			   dict_index_get_nth_field(index, i)->prefix_len)) {

			btr_index_rec_validate_report(page, rec, index);
+28 −7
Original line number Diff line number Diff line
@@ -756,9 +756,13 @@ lock_rec_has_to_wait(
	ulint	type_mode,/* in: precise mode of the new lock to set:
			LOCK_S or LOCK_X, possibly ORed to
			LOCK_GAP or LOCK_REC_NOT_GAP, LOCK_INSERT_INTENTION */
	lock_t*	lock2)	/* in: another record lock; NOTE that it is assumed
	lock_t*	lock2,	/* in: another record lock; NOTE that it is assumed
			that this has a lock bit set on the same record as
			in the new lock we are setting */
	ibool lock_is_on_supremum)  /* in: TRUE if we are setting the lock
			on the 'supremum' record of an index
			page: we know then that the lock request
			is really for a 'gap' type lock */
{
	ut_ad(trx && lock2);
	ut_ad(lock_get_type(lock2) == LOCK_REC);
@@ -770,10 +774,22 @@ lock_rec_has_to_wait(
		/* We have somewhat complex rules when gap type record locks
		cause waits */

		if ((type_mode & LOCK_REC_NOT_GAP)
		if ((lock_is_on_supremum || (type_mode & LOCK_GAP))
			&& !(type_mode & LOCK_INSERT_INTENTION)) {

			/* Gap type locks without LOCK_INSERT_INTENTION flag
			do not need to wait for anything. This is because 
			different users can have conflicting lock types 
			on gaps. */
						  
			return(FALSE);
		}
		
		if (!(type_mode & LOCK_INSERT_INTENTION)
						&& lock_rec_get_gap(lock2)) {
			/* Lock on just the record does not need to wait for
			a gap type lock */

			/* Record lock (LOCK_ORDINARY or LOCK_REC_NOT_GAP
			does not need to wait for a gap type lock */

			return(FALSE);
		}
@@ -830,8 +846,12 @@ lock_has_to_wait(
		if (lock_get_type(lock1) == LOCK_REC) {
			ut_ad(lock_get_type(lock2) == LOCK_REC);

			/* If this lock request is for a supremum record
			then the second bit on the lock bitmap is set */
			
			return(lock_rec_has_to_wait(lock1->trx,
						lock1->type_mode, lock2));
					lock1->type_mode, lock2,
					lock_rec_get_nth_bit(lock1,1)));
		}

		return(TRUE);
@@ -1420,7 +1440,8 @@ lock_rec_other_has_conflicting(
	lock = lock_rec_get_first(rec);

	while (lock) {
		if (lock_rec_has_to_wait(trx, mode, lock)) {
		if (lock_rec_has_to_wait(trx, mode, lock,
			page_rec_is_supremum(rec))) {

			return(lock);
		}
+3 −2
Original line number Diff line number Diff line
@@ -541,7 +541,8 @@ cmp_dtuple_rec_with_match(
			&& dtype_get_charset_coll(cur_type->prtype) !=
				data_mysql_latin1_swedish_charset_coll)) {

			ret = cmp_whole_field(cur_type,
			ret = cmp_whole_field(
				cur_type,
				dfield_get_data(dtuple_field), dtuple_f_len,
				rec_b_ptr, rec_f_len);

+107 −12
Original line number Diff line number Diff line
@@ -1023,6 +1023,33 @@ row_ins_set_shared_rec_lock(
	return(err);
}

/*************************************************************************
Sets a exclusive lock on a record. Used in locking possible duplicate key
records */
static
ulint
row_ins_set_exclusive_rec_lock(
/*============================*/
				/* out: DB_SUCCESS or error code */
	ulint		type, 	/* in: LOCK_ORDINARY, LOCK_GAP, or
				LOCK_REC_NOT_GAP type lock */
	rec_t*		rec,	/* in: record */
	dict_index_t*	index,	/* in: index */
	que_thr_t*	thr)	/* in: query thread */	
{
	ulint	err;

	if (index->type & DICT_CLUSTERED) {
		err = lock_clust_rec_read_check_and_lock(0, rec, index, LOCK_X,
								type, thr);
	} else {
		err = lock_sec_rec_read_check_and_lock(0, rec, index, LOCK_X,
								type, thr);
	}

	return(err);
}
	
/*******************************************************************
Checks if foreign key constraint fails for an index entry. Sets shared locks
which lock either the success or the failure of the constraint. NOTE that
@@ -1451,6 +1478,8 @@ row_ins_scan_sec_index_for_duplicate(
	ulint		err		= DB_SUCCESS;
	ibool		moved;
	mtr_t		mtr;
        trx_t           *trx;
        ibool           success;

	n_unique = dict_index_get_n_unique(index);

@@ -1488,8 +1517,24 @@ row_ins_scan_sec_index_for_duplicate(
				
		/* Try to place a lock on the index record */

		err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, rec, index,
									thr);
		trx = thr_get_trx(thr);      
		ut_ad(trx);
		dict_accept(*trx->mysql_query_str, "REPLACE", &success);

		if (success) {

			/* The manual defines the REPLACE semantics that it 
			is either an INSERT or DELETE(s) for duplicate key
			+ INSERT. Therefore, we should take X-lock for 
			duplicates */
			
			err = row_ins_set_exclusive_rec_lock(
						LOCK_ORDINARY,rec,index,thr);
		} else {

			err = row_ins_set_shared_rec_lock(
						LOCK_ORDINARY, rec, index,thr);
		}

		if (err != DB_SUCCESS) {

@@ -1556,6 +1601,7 @@ row_ins_duplicate_error_in_clust(
	page_t*	page;
	ulint	n_unique;
	trx_t*	trx	= thr_get_trx(thr);
        ibool   success;

	UT_NOT_USED(mtr);
	
@@ -1589,8 +1635,26 @@ row_ins_duplicate_error_in_clust(
			sure that in roll-forward we get the same duplicate
			errors as in original execution */

			err = row_ins_set_shared_rec_lock(LOCK_REC_NOT_GAP,
						rec, cursor->index, thr);
			dict_accept(*trx->mysql_query_str, "REPLACE", 
				    &success);

			if (success) {

				/* The manual defines the REPLACE semantics 
				that it is either an INSERT or DELETE(s) 
				for duplicate key + INSERT. Therefore, we 
				should take X-lock for duplicates */
				
				err = row_ins_set_exclusive_rec_lock(
					LOCK_REC_NOT_GAP,rec,cursor->index,
					thr);
			} else {
				
				err = row_ins_set_shared_rec_lock(
					LOCK_REC_NOT_GAP,rec, cursor->index, 
					thr);
			} 

			if (err != DB_SUCCESS) {
					
				return(err);
@@ -1611,8 +1675,30 @@ row_ins_duplicate_error_in_clust(

		if (rec != page_get_supremum_rec(page)) {

			err = row_ins_set_shared_rec_lock(LOCK_REC_NOT_GAP,

			/* The manual defines the REPLACE semantics that it 
			is either an INSERT or DELETE(s) for duplicate key
			+ INSERT. Therefore, we should take X-lock for
			duplicates.
		        */

			/* Is the first word in MySQL query REPLACE ? */

		 	dict_accept(*trx->mysql_query_str, "REPLACE", 
				    &success);

			if (success) {

				err = row_ins_set_exclusive_rec_lock(
						LOCK_REC_NOT_GAP,
						rec,cursor->index,thr);
			} else {

				err = row_ins_set_shared_rec_lock(
						LOCK_REC_NOT_GAP,rec, 
						cursor->index, thr);
			}

			if (err != DB_SUCCESS) {
					
				return(err);
@@ -1913,6 +1999,7 @@ row_ins_index_entry_set_vals(
	dfield_t*	row_field;
	ulint		n_fields;
	ulint		i;
	dtype_t*        cur_type;

	ut_ad(entry && row);

@@ -1926,10 +2013,18 @@ row_ins_index_entry_set_vals(

		/* Check column prefix indexes */
		if (ind_field->prefix_len > 0
		    && dfield_get_len(row_field) != UNIV_SQL_NULL
		    && dfield_get_len(row_field) > ind_field->prefix_len) {
		    && dfield_get_len(row_field) != UNIV_SQL_NULL) {

			/* For prefix keys get the storage length
			for the prefix_len characters. */

			cur_type = dict_col_get_type(
				dict_field_get_col(ind_field));

		        field->len = ind_field->prefix_len;
			field->len = innobase_get_at_most_n_mbchars(
				dtype_get_charset_coll(cur_type->prtype),
				ind_field->prefix_len,
				dfield_get_len(row_field),row_field->data);
		} else {
		        field->len = row_field->len;
		}
+27 −6
Original line number Diff line number Diff line
@@ -113,6 +113,8 @@ row_build_index_entry(
	dfield_t*	dfield2;
	dict_col_t*	col;
	ulint		i;
        ulint           storage_len;
	dtype_t*	cur_type;

	ut_ad(row && index && heap);
	ut_ad(dtuple_check_typed(row));
@@ -139,10 +141,20 @@ row_build_index_entry(

		/* If a column prefix index, take only the prefix */
		if (ind_field->prefix_len > 0
		    && dfield_get_len(dfield2) != UNIV_SQL_NULL
		    && dfield_get_len(dfield2) > ind_field->prefix_len) {
		    && dfield_get_len(dfield2) != UNIV_SQL_NULL) {
			
			dfield_set_len(dfield, ind_field->prefix_len);
			/* For prefix keys get the storage length
			for the prefix_len characters. */

			cur_type = dict_col_get_type(
				dict_field_get_col(ind_field));

			storage_len = innobase_get_at_most_n_mbchars(
				dtype_get_charset_coll(cur_type->prtype),
				ind_field->prefix_len,
				dfield_get_len(dfield2),dfield2->data);

			dfield_set_len(dfield,storage_len);
		}
	}

@@ -460,6 +472,7 @@ row_build_row_ref_from_row(
	dict_col_t*	col;
	ulint		ref_len;
	ulint		i;
	dtype_t*	cur_type;
	
	ut_ad(ref && table && row);
		
@@ -481,10 +494,18 @@ row_build_row_ref_from_row(
		dfield_copy(dfield, dfield2);

		if (field->prefix_len > 0
		    && dfield->len != UNIV_SQL_NULL
		    && dfield->len > field->prefix_len) {
		    && dfield->len != UNIV_SQL_NULL) {

			/* For prefix keys get the storage length
			for the prefix_len characters. */

			cur_type = dict_col_get_type(
				dict_field_get_col(field));

		        dfield->len = field->prefix_len;
			dfield->len = innobase_get_at_most_n_mbchars(
				dtype_get_charset_coll(cur_type->prtype),
				field->prefix_len,
				dfield->len,dfield->data);
		}
	}

Loading