summaryrefslogtreecommitdiff
path: root/innobase/row/row0ins.c
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2004-12-02 19:45:07 +0200
committerunknown <marko@hundin.mysql.fi>2004-12-02 19:45:07 +0200
commitd2c4b545405845900af52e033240040ee2ab83dd (patch)
treec3c716219a8f464ef096a6dd06835d4bfb627c8a /innobase/row/row0ins.c
parent4a9ef43a4961ee8795f143be4d390ab67bbf65d7 (diff)
downloadmariadb-git-d2c4b545405845900af52e033240040ee2ab83dd.tar.gz
Many files:
Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/btr/btr0btr.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/btr/btr0cur.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/btr/btr0pcur.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/btr/btr0sea.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/data/data0data.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/data/data0type.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0boot.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0crea.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0dict.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0load.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0mem.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/fil/fil0fil.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/fsp/fsp0fsp.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/ibuf/ibuf0ibuf.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0btr.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0btr.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0cur.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0cur.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0pcur.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0sea.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/data0type.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/dict0dict.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/dict0dict.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/dict0mem.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/lock0lock.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/lock0lock.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/mtr0log.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/mtr0mtr.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/page0cur.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/page0cur.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/page0page.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/page0page.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/rem0cmp.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/rem0cmp.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/rem0rec.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/rem0rec.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0row.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0row.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0upd.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0upd.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0vers.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0vers.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/srv0srv.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/trx0rec.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/ut0byte.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/ut0byte.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/lock/lock0lock.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/log/log0recv.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/mtr/mtr0log.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/page/page0cur.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/page/page0page.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/pars/pars0pars.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/rem/rem0cmp.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/rem/rem0rec.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0ins.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0mysql.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0purge.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0row.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0sel.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0umod.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0undo.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0upd.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0vers.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/srv/srv0srv.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/trx/trx0rec.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/trx/trx0undo.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. sql/ha_innodb.cc: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC.
Diffstat (limited to 'innobase/row/row0ins.c')
-rw-r--r--innobase/row/row0ins.c213
1 files changed, 149 insertions, 64 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 6d1482b6720..c3149401f3c 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -251,7 +251,7 @@ row_ins_sec_index_entry_by_modify(
rec = btr_cur_get_rec(cursor);
ut_ad((cursor->index->type & DICT_CLUSTERED) == 0);
- ut_ad(rec_get_deleted_flag(rec));
+ ut_ad(rec_get_deleted_flag(rec, cursor->index->table->comp));
/* We know that in the alphabetical ordering, entry and rec are
identified. But in their binary form there may be differences if
@@ -316,7 +316,7 @@ row_ins_clust_index_entry_by_modify(
rec = btr_cur_get_rec(cursor);
- ut_ad(rec_get_deleted_flag(rec));
+ ut_ad(rec_get_deleted_flag(rec, cursor->index->table->comp));
heap = mem_heap_create(1024);
@@ -588,8 +588,16 @@ row_ins_foreign_report_err(
fputs(", in index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name);
if (rec) {
+ mem_heap_t* heap;
+ ulint* offsets;
+
+ heap = mem_heap_create(100);
+ offsets = rec_get_offsets(rec, foreign->foreign_index,
+ ULINT_UNDEFINED, heap);
+
fputs(", there is a record:\n", ef);
- rec_print(ef, rec);
+ rec_print(ef, rec, offsets);
+ mem_heap_free(heap);
} else {
fputs(", the record is not available\n", ef);
}
@@ -644,7 +652,16 @@ row_ins_foreign_report_add_err(
}
if (rec) {
- rec_print(ef, rec);
+ mem_heap_t* heap;
+ ulint* offsets;
+
+ heap = mem_heap_create(100);
+ offsets = rec_get_offsets(rec, foreign->foreign_index,
+ ULINT_UNDEFINED, heap);
+
+ rec_print(ef, rec, offsets);
+
+ mem_heap_free(heap);
}
putc('\n', ef);
@@ -706,7 +723,6 @@ row_ins_foreign_check_on_constraint(
dict_index_t* index;
dict_index_t* clust_index;
dtuple_t* ref;
- mem_heap_t* tmp_heap;
mem_heap_t* upd_vec_heap = NULL;
rec_t* rec;
rec_t* clust_rec;
@@ -715,8 +731,9 @@ row_ins_foreign_check_on_constraint(
ulint err;
ulint i;
trx_t* trx;
+ mem_heap_t* tmp_heap = NULL;
+ ulint* offsets;
-
ut_a(thr && foreign && pcur && mtr);
trx = thr_get_trx(thr);
@@ -816,7 +833,7 @@ row_ins_foreign_check_on_constraint(
err = DB_ROW_IS_REFERENCED;
row_ins_foreign_report_err(
-(char*)"Trying a too deep cascaded delete or update\n",
+"Trying a too deep cascaded delete or update\n",
thr, foreign, btr_pcur_get_rec(pcur), entry);
goto nonstandard_exit_func;
@@ -848,8 +865,6 @@ row_ins_foreign_check_on_constraint(
PAGE_CUR_LE, BTR_SEARCH_LEAF,
cascade->pcur, 0, mtr);
- mem_heap_free(tmp_heap);
-
clust_rec = btr_pcur_get_rec(cascade->pcur);
if (!page_rec_is_user_rec(clust_rec)
@@ -863,10 +878,14 @@ row_ins_foreign_check_on_constraint(
fputs("\n"
"InnoDB: record ", stderr);
- rec_print(stderr, rec);
+ offsets = rec_get_offsets(rec, index,
+ ULINT_UNDEFINED, tmp_heap);
+ rec_print(stderr, rec, offsets);
fputs("\n"
"InnoDB: clustered record ", stderr);
- rec_print(stderr, clust_rec);
+ offsets = rec_reget_offsets(clust_rec, clust_index,
+ offsets, ULINT_UNDEFINED, tmp_heap);
+ rec_print(stderr, clust_rec, offsets);
fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
@@ -884,9 +903,14 @@ row_ins_foreign_check_on_constraint(
/* Here it suffices to use a LOCK_REC_NOT_GAP type lock;
we already have a normal shared lock on the appropriate
gap if the search criterion was not unique */
-
+
+ if (!tmp_heap) {
+ tmp_heap = mem_heap_create(256);
+ }
+ offsets = rec_get_offsets(clust_rec, clust_index,
+ ULINT_UNDEFINED, tmp_heap);
err = lock_clust_rec_read_check_and_lock(0, clust_rec,
- clust_index, LOCK_X, LOCK_REC_NOT_GAP, thr);
+ clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr);
}
if (err != DB_SUCCESS) {
@@ -894,7 +918,7 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
- if (rec_get_deleted_flag(clust_rec)) {
+ if (rec_get_deleted_flag(clust_rec, table->comp)) {
/* This can happen if there is a circular reference of
rows such that cascading delete comes to delete a row
already in the process of being delete marked */
@@ -1003,6 +1027,10 @@ row_ins_foreign_check_on_constraint(
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
+ if (tmp_heap) {
+ mem_heap_free(tmp_heap);
+ }
+
if (upd_vec_heap) {
mem_heap_free(upd_vec_heap);
}
@@ -1010,6 +1038,9 @@ row_ins_foreign_check_on_constraint(
return(err);
nonstandard_exit_func:
+ if (tmp_heap) {
+ mem_heap_free(tmp_heap);
+ }
if (upd_vec_heap) {
mem_heap_free(upd_vec_heap);
@@ -1037,16 +1068,19 @@ row_ins_set_shared_rec_lock(
LOCK_REC_NOT_GAP type lock */
rec_t* rec, /* in: record */
dict_index_t* index, /* in: index */
+ const ulint* offsets,/* in: rec_get_offsets(rec, index) */
que_thr_t* thr) /* in: query thread */
{
ulint err;
+ ut_ad(rec_offs_validate(rec, index, offsets));
+
if (index->type & DICT_CLUSTERED) {
- err = lock_clust_rec_read_check_and_lock(0, rec, index, LOCK_S,
- type, thr);
+ err = lock_clust_rec_read_check_and_lock(0,
+ rec, index, offsets, LOCK_S, type, thr);
} else {
- err = lock_sec_rec_read_check_and_lock(0, rec, index, LOCK_S,
- type, thr);
+ err = lock_sec_rec_read_check_and_lock(0,
+ rec, index, offsets, LOCK_S, type, thr);
}
return(err);
@@ -1064,16 +1098,19 @@ row_ins_set_exclusive_rec_lock(
LOCK_REC_NOT_GAP type lock */
rec_t* rec, /* in: record */
dict_index_t* index, /* in: index */
+ const ulint* offsets,/* in: rec_get_offsets(rec, index) */
que_thr_t* thr) /* in: query thread */
{
ulint err;
+ ut_ad(rec_offs_validate(rec, index, offsets));
+
if (index->type & DICT_CLUSTERED) {
- err = lock_clust_rec_read_check_and_lock(0, rec, index, LOCK_X,
- type, thr);
+ err = lock_clust_rec_read_check_and_lock(0,
+ rec, index, offsets, LOCK_X, type, thr);
} else {
- err = lock_sec_rec_read_check_and_lock(0, rec, index, LOCK_X,
- type, thr);
+ err = lock_sec_rec_read_check_and_lock(0,
+ rec, index, offsets, LOCK_X, type, thr);
}
return(err);
@@ -1114,6 +1151,10 @@ row_ins_check_foreign_constraint(
ulint i;
mtr_t mtr;
trx_t* trx = thr_get_trx(thr);
+ mem_heap_t* heap;
+ ulint* offsets = NULL;
+
+ heap = mem_heap_create(100);
run_again:
#ifdef UNIV_SYNC_DEBUG
@@ -1125,7 +1166,7 @@ run_again:
if (trx->check_foreigns == FALSE) {
/* The user has suppressed foreign key checks currently for
this session */
-
+ mem_heap_free(heap);
return(DB_SUCCESS);
}
@@ -1137,6 +1178,7 @@ run_again:
if (UNIV_SQL_NULL == dfield_get_len(
dtuple_get_nth_field(entry, i))) {
+ mem_heap_free(heap);
return(DB_SUCCESS);
}
}
@@ -1160,7 +1202,8 @@ run_again:
with each foreign key constraint, one after
another, and the user has problems predicting in
which order they are performed. */
-
+
+ mem_heap_free(heap);
return(DB_SUCCESS);
}
}
@@ -1174,6 +1217,8 @@ run_again:
}
if (check_table == NULL) {
+ mem_heap_free(heap);
+
if (check_ref) {
FILE* ef = dict_foreign_err_file;
mutex_enter(&dict_foreign_err_mutex);
@@ -1244,10 +1289,13 @@ run_again:
goto next_rec;
}
+ offsets = rec_reget_offsets(rec, check_index,
+ offsets, ULINT_UNDEFINED, heap);
+
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
-
+
err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, rec,
- check_index, thr);
+ check_index, offsets, thr);
if (err != DB_SUCCESS) {
break;
@@ -1256,29 +1304,30 @@ run_again:
goto next_rec;
}
- cmp = cmp_dtuple_rec(entry, rec);
+ cmp = cmp_dtuple_rec(entry, rec, offsets);
if (cmp == 0) {
- if (rec_get_deleted_flag(rec)) {
+ if (rec_get_deleted_flag(rec,
+ rec_offs_comp(offsets))) {
err = row_ins_set_shared_rec_lock(
- LOCK_ORDINARY,
- rec, check_index, thr);
+ LOCK_ORDINARY, rec,
+ check_index, offsets, thr);
if (err != DB_SUCCESS) {
break;
}
} else {
/* Found a matching record */
+ ulint lock_type;
if (unique_search) {
- err = row_ins_set_shared_rec_lock(
- LOCK_REC_NOT_GAP,
- rec, check_index, thr);
+ lock_type = LOCK_REC_NOT_GAP;
} else {
- err = row_ins_set_shared_rec_lock(
- LOCK_ORDINARY,
- rec, check_index, thr);
+ lock_type = LOCK_ORDINARY;
}
+
+ err = row_ins_set_shared_rec_lock(lock_type,
+ rec, check_index, offsets, thr);
if (err != DB_SUCCESS) {
@@ -1315,7 +1364,7 @@ run_again:
if (cmp < 0) {
err = row_ins_set_shared_rec_lock(LOCK_GAP,
- rec, check_index, thr);
+ rec, check_index, offsets, thr);
if (err != DB_SUCCESS) {
break;
@@ -1373,6 +1422,7 @@ do_possible_lock_wait:
err = trx->error_state;
}
+ mem_heap_free(heap);
return(err);
}
@@ -1444,19 +1494,23 @@ row_ins_dupl_error_with_rec(
that the caller already has a record lock on
the record! */
dtuple_t* entry, /* in: entry to insert */
- dict_index_t* index) /* in: index */
+ dict_index_t* index, /* in: index */
+ const ulint* offsets)/* in: rec_get_offsets(rec, index) */
{
ulint matched_fields;
ulint matched_bytes;
ulint n_unique;
ulint i;
-
+
+ ut_ad(rec_offs_validate(rec, index, offsets));
+
n_unique = dict_index_get_n_unique(index);
matched_fields = 0;
matched_bytes = 0;
- cmp_dtuple_rec_with_match(entry, rec, &matched_fields, &matched_bytes);
+ cmp_dtuple_rec_with_match(entry, rec, offsets,
+ &matched_fields, &matched_bytes);
if (matched_fields < n_unique) {
@@ -1477,7 +1531,7 @@ row_ins_dupl_error_with_rec(
}
}
- if (!rec_get_deleted_flag(rec)) {
+ if (!rec_get_deleted_flag(rec, index->table->comp)) {
return(TRUE);
}
@@ -1509,7 +1563,9 @@ row_ins_scan_sec_index_for_duplicate(
ibool moved;
mtr_t mtr;
trx_t* trx;
-
+ mem_heap_t* heap;
+ ulint* offsets = NULL;
+
n_unique = dict_index_get_n_unique(index);
/* If the secondary index is unique, but one of the fields in the
@@ -1524,6 +1580,7 @@ row_ins_scan_sec_index_for_duplicate(
}
}
+ heap = mem_heap_create(100);
mtr_start(&mtr);
/* Store old value on n_fields_cmp */
@@ -1549,6 +1606,9 @@ row_ins_scan_sec_index_for_duplicate(
trx = thr_get_trx(thr);
ut_ad(trx);
+ offsets = rec_reget_offsets(rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+
if (innobase_query_is_replace()) {
/* The manual defines the REPLACE semantics that it
@@ -1556,12 +1616,12 @@ row_ins_scan_sec_index_for_duplicate(
+ INSERT. Therefore, we should take X-lock for
duplicates */
- err = row_ins_set_exclusive_rec_lock(
- LOCK_ORDINARY,rec,index,thr);
+ err = row_ins_set_exclusive_rec_lock(LOCK_ORDINARY,
+ rec, index, offsets, thr);
} else {
- err = row_ins_set_shared_rec_lock(
- LOCK_ORDINARY, rec, index,thr);
+ err = row_ins_set_shared_rec_lock(LOCK_ORDINARY,
+ rec, index, offsets, thr);
}
if (err != DB_SUCCESS) {
@@ -1574,10 +1634,11 @@ row_ins_scan_sec_index_for_duplicate(
goto next_rec;
}
- cmp = cmp_dtuple_rec(entry, rec);
+ cmp = cmp_dtuple_rec(entry, rec, offsets);
if (cmp == 0) {
- if (row_ins_dupl_error_with_rec(rec, entry, index)) {
+ if (row_ins_dupl_error_with_rec(rec, entry,
+ index, offsets)) {
err = DB_DUPLICATE_KEY;
thr_get_trx(thr)->error_info = index;
@@ -1599,6 +1660,7 @@ next_rec:
}
}
+ mem_heap_free(heap);
mtr_commit(&mtr);
/* Restore old value */
@@ -1656,6 +1718,12 @@ row_ins_duplicate_error_in_clust(
page = buf_frame_align(rec);
if (rec != page_get_infimum_rec(page)) {
+ mem_heap_t* heap;
+ ulint* offsets;
+
+ heap = mem_heap_create(100);
+ offsets = rec_get_offsets(rec, cursor->index,
+ ULINT_UNDEFINED, heap);
/* We set a lock on the possible duplicate: this
is needed in logical logging of MySQL to make
@@ -1671,24 +1739,26 @@ row_ins_duplicate_error_in_clust(
err = row_ins_set_exclusive_rec_lock(
LOCK_REC_NOT_GAP,rec,cursor->index,
- thr);
+ offsets, thr);
} else {
err = row_ins_set_shared_rec_lock(
LOCK_REC_NOT_GAP,rec, cursor->index,
- thr);
+ offsets, thr);
}
if (err != DB_SUCCESS) {
-
+ mem_heap_free(heap);
return(err);
}
if (row_ins_dupl_error_with_rec(rec, entry,
- cursor->index)) {
+ cursor->index, offsets)) {
trx->error_info = cursor->index;
+ mem_heap_free(heap);
return(DB_DUPLICATE_KEY);
}
+ mem_heap_free(heap);
}
}
@@ -1698,7 +1768,12 @@ row_ins_duplicate_error_in_clust(
page = buf_frame_align(rec);
if (rec != page_get_supremum_rec(page)) {
+ mem_heap_t* heap;
+ ulint* offsets;
+ heap = mem_heap_create(100);
+ offsets = rec_get_offsets(rec, cursor->index,
+ ULINT_UNDEFINED, heap);
/* The manual defines the REPLACE semantics that it
is either an INSERT or DELETE(s) for duplicate key
@@ -1708,25 +1783,27 @@ row_ins_duplicate_error_in_clust(
if (innobase_query_is_replace()) {
err = row_ins_set_exclusive_rec_lock(
- LOCK_REC_NOT_GAP,
- rec,cursor->index,thr);
+ LOCK_REC_NOT_GAP, rec,
+ cursor->index, offsets, thr);
} else {
err = row_ins_set_shared_rec_lock(
- LOCK_REC_NOT_GAP,rec,
- cursor->index, thr);
+ LOCK_REC_NOT_GAP, rec,
+ cursor->index, offsets, thr);
}
if (err != DB_SUCCESS) {
-
+ mem_heap_free(heap);
return(err);
}
if (row_ins_dupl_error_with_rec(rec, entry,
- cursor->index)) {
+ cursor->index, offsets)) {
trx->error_info = cursor->index;
+ mem_heap_free(heap);
return(DB_DUPLICATE_KEY);
}
+ mem_heap_free(heap);
}
ut_a(!(cursor->index->type & DICT_CLUSTERED));
@@ -1815,6 +1892,8 @@ row_ins_index_entry_low(
ulint n_unique;
big_rec_t* big_rec = NULL;
mtr_t mtr;
+ mem_heap_t* heap = mem_heap_create(100);
+ ulint* offsets = NULL;
log_free_check();
@@ -1847,8 +1926,9 @@ row_ins_index_entry_low(
buf_frame_align(btr_cur_get_rec(&cursor))));
if (!page_rec_is_supremum(first_rec)) {
- ut_a((rec_get_n_fields(first_rec))
- == dtuple_get_n_fields(entry));
+ offsets = rec_get_offsets(first_rec, index,
+ ULINT_UNDEFINED, heap);
+ ut_a(rec_offs_n_fields(offsets) == dtuple_get_n_fields(entry));
}
n_unique = dict_index_get_n_unique(index);
@@ -1926,7 +2006,7 @@ row_ins_index_entry_low(
if (err == DB_SUCCESS) {
if (ext_vec) {
- rec_set_field_extern_bits(insert_rec,
+ rec_set_field_extern_bits(insert_rec, index,
ext_vec, n_ext_vec, &mtr);
}
}
@@ -1936,14 +2016,18 @@ 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_reget_offsets(rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+
+ err = btr_store_big_rec_extern_fields(index, rec,
+ offsets, big_rec, &mtr);
- err = btr_store_big_rec_extern_fields(index,
- btr_cur_get_rec(&cursor),
- big_rec, &mtr);
if (modify) {
dtuple_big_rec_free(big_rec);
} else {
@@ -1953,6 +2037,7 @@ function_exit:
mtr_commit(&mtr);
}
+ mem_heap_free(heap);
return(err);
}