summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlfranio Correia <alfranio.correia@sun.com>2009-09-29 15:04:21 +0100
committerAlfranio Correia <alfranio.correia@sun.com>2009-09-29 15:04:21 +0100
commitcc9e25af54ac0a00cfe9930253a0e6de70f0c668 (patch)
tree32c92fb795b247ef55dd2ceda67073ba4abb2f1a /sql
parentb7f887652b22d49574860d6948e67f0ea7a83294 (diff)
downloadmariadb-git-cc9e25af54ac0a00cfe9930253a0e6de70f0c668.tar.gz
BUG#38173 Field doesn't have a default value with row-based replication
NOTE: Backporting the patch to next-mr. The reason of the bug was incompatibile with the master side behaviour. INSERT query on the master is allowed to insert into a table without specifying values of DEFAULT-less fields if sql_mode is not strict. Fixed with checking sql_mode by the sql thread to decide how to react. Non-strict sql_mode should allow Write_rows event to complete. todo: warnings can be shown via show slave status, still this is a separate rather general issue how to show warnings for the slave threads.
Diffstat (limited to 'sql')
-rw-r--r--sql/log_event.cc5
-rw-r--r--sql/rpl_record.cc34
-rw-r--r--sql/rpl_record.h3
3 files changed, 30 insertions, 12 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index fb6a5230fda..d595f00bffd 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -8446,7 +8446,10 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
/* fill table->record[0] with default values */
if ((error= prepare_record(table, m_width,
- TRUE /* check if columns have def. values */)))
+ table->file->ht->db_type != DB_TYPE_NDBCLUSTER,
+ (rli->sql_thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES |
+ MODE_STRICT_ALL_TABLES)))))
DBUG_RETURN(error);
/* unpack row into table->record[0] */
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index 14a80cbb4b6..f4768e2456a 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -305,13 +305,17 @@ unpack_row(Relay_log_info const *rli,
@param table Table whose record[0] buffer is prepared.
@param skip Number of columns for which default/nullable check
should be skipped.
- @param check Indicates if errors should be raised when checking
- default/nullable field properties.
+ @param check Specifies if lack of default error needs checking.
+ @param abort_on_warning
+ Controls how to react on lack of a field's default.
+ The parameter mimics the master side one for
+ @c check_that_all_fields_are_given_values.
@returns 0 on success or a handler level error code
*/
int prepare_record(TABLE *const table,
- const uint skip, const bool check)
+ const uint skip, const bool check,
+ const bool abort_on_warning)
{
DBUG_ENTER("prepare_record");
@@ -326,17 +330,27 @@ int prepare_record(TABLE *const table,
if (skip >= table->s->fields || !check)
DBUG_RETURN(0);
- /* Checking if exists default/nullable fields in the default values. */
-
- for (Field **field_ptr= table->field+skip ; *field_ptr ; ++field_ptr)
+ /*
+ For fields the extra fields on the slave, we check if they have a default.
+ The check follows the same rules as the INSERT query without specifying an
+ explicit value for a field not having the explicit default
+ (@c check_that_all_fields_are_given_values()).
+ */
+ for (Field **field_ptr= table->field+skip; *field_ptr; ++field_ptr)
{
uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
Field *const f= *field_ptr;
-
- if (((f->flags & mask) == mask))
+ if ((f->flags & NO_DEFAULT_VALUE_FLAG) &&
+ (f->real_type() != MYSQL_TYPE_ENUM))
{
- my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
- error = HA_ERR_ROWS_EVENT_APPLY;
+ push_warning_printf(current_thd, abort_on_warning?
+ MYSQL_ERROR::WARN_LEVEL_ERROR :
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_NO_DEFAULT_FOR_FIELD,
+ ER(ER_NO_DEFAULT_FOR_FIELD),
+ f->field_name);
+ if (abort_on_warning)
+ error = HA_ERR_ROWS_EVENT_APPLY;
}
}
diff --git a/sql/rpl_record.h b/sql/rpl_record.h
index f9e64f0ab1d..ab2bcd382ca 100644
--- a/sql/rpl_record.h
+++ b/sql/rpl_record.h
@@ -30,7 +30,8 @@ int unpack_row(Relay_log_info const *rli,
uchar const **const row_end, ulong *const master_reclength);
// Fill table's record[0] with default values.
-int prepare_record(TABLE *const, const uint =0, const bool =FALSE);
+int prepare_record(TABLE *const table, const uint skip, const bool check,
+ const bool abort_on_warning= FALSE);
#endif
#endif