summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2015-07-09 14:47:32 +0300
committerMonty <monty@mariadb.org>2015-07-09 14:47:32 +0300
commit9bb8b74e99adced1ccb38ced24a96cf2d1040f39 (patch)
treec58f67cd054fa8829ca11d275f86db7691031eb2 /sql/table.cc
parenta6c801438717b815288acb72513f5e42fe736b7b (diff)
parent77803703431d79f5dcc2b23b3f878dfdbaf01c2b (diff)
downloadmariadb-git-9bb8b74e99adced1ccb38ced24a96cf2d1040f39.tar.gz
Merge branch '10.1' of github.com:MariaDB/server into 10.1
Conflicts: sql/item_subselect.cc Fixed also typo in comment
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc102
1 files changed, 102 insertions, 0 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 5b31ea0de3e..7a56be14731 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -5829,6 +5829,8 @@ void TABLE::mark_auto_increment_column()
void TABLE::mark_columns_needed_for_delete()
{
+ mark_columns_per_binlog_row_image();
+
if (triggers)
triggers->mark_fields_used(TRG_EVENT_DELETE);
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
@@ -5880,6 +5882,9 @@ void TABLE::mark_columns_needed_for_delete()
void TABLE::mark_columns_needed_for_update()
{
DBUG_ENTER("mark_columns_needed_for_update");
+
+ mark_columns_per_binlog_row_image();
+
if (triggers)
triggers->mark_fields_used(TRG_EVENT_UPDATE);
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
@@ -5924,6 +5929,8 @@ void TABLE::mark_columns_needed_for_update()
void TABLE::mark_columns_needed_for_insert()
{
+ mark_columns_per_binlog_row_image();
+
if (triggers)
{
/*
@@ -5941,6 +5948,101 @@ void TABLE::mark_columns_needed_for_insert()
mark_virtual_columns_for_write(TRUE);
}
+/*
+ Mark columns according the binlog row image option.
+
+ When logging in RBR, the user can select whether to
+ log partial or full rows, depending on the table
+ definition, and the value of binlog_row_image.
+
+ Semantics of the binlog_row_image are the following
+ (PKE - primary key equivalent, ie, PK fields if PK
+ exists, all fields otherwise):
+
+ binlog_row_image= MINIMAL
+ - This marks the PKE fields in the read_set
+ - This marks all fields where a value was specified
+ in the write_set
+
+ binlog_row_image= NOBLOB
+ - This marks PKE + all non-blob fields in the read_set
+ - This marks all fields where a value was specified
+ and all non-blob fields in the write_set
+
+ binlog_row_image= FULL
+ - all columns in the read_set
+ - all columns in the write_set
+
+ This marking is done without resetting the original
+ bitmaps. This means that we will strip extra fields in
+ the read_set at binlogging time (for those cases that
+ we only want to log a PK and we needed other fields for
+ execution).
+*/
+void TABLE::mark_columns_per_binlog_row_image()
+{
+ DBUG_ENTER("mark_columns_per_binlog_row_image");
+ DBUG_ASSERT(read_set->bitmap);
+ DBUG_ASSERT(write_set->bitmap);
+
+ /**
+ If in RBR we may need to mark some extra columns,
+ depending on the binlog-row-image command line argument.
+ */
+ if ((mysql_bin_log.is_open() && in_use &&
+ in_use->is_current_stmt_binlog_format_row() &&
+ !ha_check_storage_engine_flag(s->db_type(), HTON_NO_BINLOG_ROW_OPT)))
+ {
+
+ THD *thd= current_thd;
+
+ /* if there is no PK, then mark all columns for the BI. */
+ if (s->primary_key >= MAX_KEY)
+ bitmap_set_all(read_set);
+
+ switch (thd->variables.binlog_row_image)
+ {
+ case BINLOG_ROW_IMAGE_FULL:
+ if (s->primary_key < MAX_KEY)
+ bitmap_set_all(read_set);
+ bitmap_set_all(write_set);
+ break;
+ case BINLOG_ROW_IMAGE_NOBLOB:
+ /* for every field that is not set, mark it unless it is a blob */
+ for (Field **ptr=field ; *ptr ; ptr++)
+ {
+ Field *my_field= *ptr;
+ /*
+ bypass blob fields. These can be set or not set, we don't care.
+ Later, at binlogging time, if we don't need them in the before
+ image, we will discard them.
+
+ If set in the AI, then the blob is really needed, there is
+ nothing we can do about it.
+ */
+ if ((s->primary_key < MAX_KEY) &&
+ ((my_field->flags & PRI_KEY_FLAG) ||
+ (my_field->type() != MYSQL_TYPE_BLOB)))
+ bitmap_set_bit(read_set, my_field->field_index);
+
+ if (my_field->type() != MYSQL_TYPE_BLOB)
+ bitmap_set_bit(write_set, my_field->field_index);
+ }
+ break;
+ case BINLOG_ROW_IMAGE_MINIMAL:
+ /* mark the primary key if available in the read_set */
+ if (s->primary_key < MAX_KEY)
+ mark_columns_used_by_index_no_reset(s->primary_key, read_set);
+ break;
+
+ default:
+ DBUG_ASSERT(FALSE);
+ }
+ file->column_bitmaps_signal();
+ }
+
+ DBUG_VOID_RETURN;
+}
/*
@brief Mark a column as virtual used by the query