summaryrefslogtreecommitdiff
path: root/innobase/row/row0sel.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/row/row0sel.c')
-rw-r--r--innobase/row/row0sel.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index ea5b3020c08..34f951b0c8a 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -2039,9 +2039,12 @@ Note that the template in prebuilt may advise us to copy only a few
columns to mysql_rec, other columns are left blank. All columns may not
be needed in the query. */
static
-void
+ibool
row_sel_store_mysql_rec(
/*====================*/
+ /* out: TRUE if success, FALSE
+ if could not allocate memory for a
+ BLOB */
byte* mysql_rec, /* out: row in the MySQL format */
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
rec_t* rec) /* in: Innobase record in the index
@@ -2092,7 +2095,19 @@ row_sel_store_mysql_rec(
if (templ->type == DATA_BLOB) {
ut_a(prebuilt->templ_contains_blob);
-
+
+ /* A heuristic test that we can allocate
+ the memory for a big BLOB. We have a safety
+ margin of 1000000 bytes. Since the test
+ takes some CPU time, we do not use for small
+ BLOBs. */
+
+ if (len > 2000000
+ && !ut_test_malloc(len + 1000000)) {
+
+ return(FALSE);
+ }
+
/* Copy the BLOB data to the BLOB
heap of prebuilt */
@@ -2142,6 +2157,8 @@ row_sel_store_mysql_rec(
}
}
}
+
+ return(TRUE);
}
/*************************************************************************
@@ -2526,7 +2543,8 @@ row_search_for_mysql(
/*=================*/
/* out: DB_SUCCESS,
DB_RECORD_NOT_FOUND,
- DB_END_OF_INDEX, or DB_DEADLOCK */
+ DB_END_OF_INDEX, DB_DEADLOCK,
+ or DB_TOO_BIG_RECORD */
byte* buf, /* in/out: buffer for the fetched
row in the MySQL format */
ulint mode, /* in: search mode PAGE_CUR_L, ... */
@@ -2758,7 +2776,12 @@ row_search_for_mysql(
#ifdef UNIV_SEARCH_DEBUG
ut_a(0 == cmp_dtuple_rec(search_tuple, rec));
#endif
- row_sel_store_mysql_rec(buf, prebuilt, rec);
+ if (!row_sel_store_mysql_rec(buf, prebuilt,
+ rec)) {
+ err = DB_TOO_BIG_RECORD;
+
+ goto lock_wait_or_error;
+ }
mtr_commit(&mtr);
@@ -3200,7 +3223,11 @@ rec_loop:
rec_get_size(rec));
mach_write_to_4(buf, rec_get_extra_size(rec) + 4);
} else {
- row_sel_store_mysql_rec(buf, prebuilt, rec);
+ if (!row_sel_store_mysql_rec(buf, prebuilt, rec)) {
+ err = DB_TOO_BIG_RECORD;
+
+ goto lock_wait_or_error;
+ }
}
if (prebuilt->clust_index_was_generated) {