summaryrefslogtreecommitdiff
path: root/sql/sql_load.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-11-23 16:42:09 +0100
committerSergei Golubchik <serg@mariadb.org>2016-12-12 20:27:38 +0100
commitf73bdb685d77b944f4565e0a97778faa30999145 (patch)
tree3d9eb5f5e830757782de891e70865aafe83c84be /sql/sql_load.cc
parentaebb1038aab6cadc3408fc194d1d9331d2b673ff (diff)
downloadmariadb-git-f73bdb685d77b944f4565e0a97778faa30999145.tar.gz
bugfix: UPDATE and virtual BLOBs
When updating a table with virtual BLOB columns, the following might happen: - an old record is read from the table, it has no virtual blob values - update_virtual_fields() is run, vcol blob gets its value into the record. But only a pointer to the value is in the table->record[0], the value is in Field_blob::value String (but it doesn't have to be! it can be in the record, if the column is just a copy of another columns: ... b VARCHAR, c BLOB AS (b) ...) - store_record(table,record[1]), old record now is in record[1] - fill_record() prepares new values in record[0], vcol blob is updated, new value replaces the old one in the Field_blob::value - now both record[1] and record[0] have a pointer that points to the *new* vcol blob value. Or record[1] has a pointer to nowhere if Field_blob::value had to realloc. To resolve this we unlink vcol blobs from the pointer to the data (in the record[1]). Because the value is not *always* in the Field_blob::value String, we need to remember what blobs were unlinked. The orphan memory must be freed manually. To complicate the matter, ha_update_row() is also used in multi-update, in REPLACE, in INSERT ... ON DUPLICATE KEY UPDATE, also on REPLACE ... SELECT, REPLACE DELAYED, and LOAD DATA REPLACE, etc
Diffstat (limited to 'sql/sql_load.cc')
-rw-r--r--sql/sql_load.cc6
1 files changed, 6 insertions, 0 deletions
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index e306097afbe..7ade7a64470 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -539,6 +539,12 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)))
? (*escaped)[0] : INT_MAX;
+ if (handle_duplicates != DUP_ERROR)
+ {
+ info.vblobs0.init(table);
+ info.vblobs1.init(table);
+ }
+
READ_INFO read_info(thd, file, tot_length,
ex->cs ? ex->cs : thd->variables.collation_database,
*field_term,*ex->line_start, *ex->line_term, *enclosed,