List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:August 23 2007 1:00pm
Subject:Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part2
View as plain text  
Hi,

OK. I'm fine with that.

/Matz

Rafal Somla wrote:
> Hi,
>
> This is a second issue which needs clarification. Tell me if you 
> disagree. (there is more to come...).
>
> Mats Kindahl wrote:
>>> +int Rows_log_event::find_and_fetch_row()
>>> +{
>>> +  DBUG_ENTER("find_and_fetch_row");
>>>  
>>> -  @pre <code>table->record[0]</code> shall contain the row to
> locate
>>> -  and <code>key</code> shall contain a key to use for searching,
> if
>>> -  the engine has a key.
>>> -
>>> -  @post If the return value is zero,
> <code>table->record[1]</code>
>>> -  will contain the fetched row and the internal "cursor" will refer to
>>> -  the row. If the return value is non-zero,
>>> -  <code>table->record[1]</code> is undefined.  In either
> case,
>>> -  <code>table->record[0]</code> is undefined.
>>> +  DBUG_ASSERT(m_table && m_table->in_use != NULL);
>>>  
>>> -  @return Zero if the row was successfully fetched into
>>> -  <code>table->record[1]</code>, error code otherwise.
>>> - */
>>> +  int error;
>>>  
>>> -static int find_and_fetch_row(TABLE *table, uchar *key)
>>> -{
>>> -  DBUG_ENTER("find_and_fetch_row(TABLE *table, uchar *key, uchar 
>>> *record)");
>>> -  DBUG_PRINT("enter", ("table: 0x%lx, key: 0x%lx  record: 0x%lx",
>>> -               (long) table, (long) key, (long) table->record[1]));
>>> +  /* unpack row - missing fields get default values */
>>> +
>>> +  prepare_record(NULL,m_table,m_width,FALSE /* don't check errors 
>>> */); // TODO: shall we check and report errors here?
>>>   
>>
>> Yes, I think so. With some exceptions, I think we should try to 
>> generate the error where it occurs. That will allow us to generate 
>> better error messages. It will also be obvious if an error code is 
>> checked or not. No need to do a major rework, though, if that turns 
>> out to be the case.
>>
>
> I'm not so sure. Looking at the code before patch, what happened there 
> was that inside ev->do_apply_event() for each row first 
> ev->do_prepare_row() was called followed by ev->do_exec_row(). Row 
> unpacking happened inside do_prepare_row(), e.g.:
>
> int Write_rows_log_event::do_prepare_row(THD *thd, Relay_log_info 
> const *rli,
>                                          TABLE *table,
>                                          uchar const *const row_start,
>                                          uchar const **const row_end)
> {
>   DBUG_ASSERT(table != NULL);
>   DBUG_ASSERT(row_start && row_end);
>
>   if (int error= unpack_row(rli, table, m_width, row_start, &m_cols, 
> row_end,
>                             &m_master_reclength, table->write_set, 
> WRITE_ROWS_EVENT))
>   {
>     thd->net.last_errno= error;
>     return error;
>   }
>   bitmap_copy(table->read_set, table->write_set);
>   return 0;
> }
>
> The last argument to unpack_row, the event type, decided about error 
> checking and reporting. Look at the old code of unpack_row():
>
>   (...)
>   /*
>     Set properties for remaining columns, if there are any. We let the
>     corresponding bit in the write_set be set, to write the value if
>     it was not there already. We iterate over all remaining columns,
>     even if there were an error, to get as many error messages as
>     possible.  We are still able to return a pointer to the next row,
>     so redo that.
>
>     This generation of error messages is only relevant when inserting
>     new rows.
>    */
>   for ( ; *field_ptr ; ++field_ptr)
>   {
>     uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
>     Field *const f= *field_ptr;
>
>     if (event_type == WRITE_ROWS_EVENT &&
>         ((*field_ptr)->flags & mask) == mask)
>     {
>       rli->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
>                   "Field `%s` of table `%s`.`%s` "
>                   "has no default value and cannot be NULL",
>                   (*field_ptr)->field_name, table->s->db.str,
>                   table->s->table_name.str);
>       error = ER_NO_DEFAULT_FOR_FIELD;
>     }
>     else
>       f->set_default();
>   }
>
> Thus error reporting happened only in case of Write_rows_log_event, 
> not for Update_rows_log_event and Delete_rows_log_event. Only the two 
> latter classes use find_and_fetch_row() hence to preserve old 
> behaviour we should not check for errors here. Perhaps it was not 
> correct from the beginning but I think that if this is the case we 
> should make a separate bug report. As for this patch, it preserves old 
> behaviour changing only things described in the proposed solution.
>
> Rafal
>


-- 
Mats Kindahl
Lead Software Developer
Replication Team
MySQL AB, www.mysql.com


Thread
bk commit into 5.1 tree (rafal:1.2530) BUG#21842rsomla6 Jul
  • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842Andrei Elkin10 Jul
  • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842Mats Kindahl22 Aug
    • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842Mats Kindahl23 Aug
    • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part 1Rafal Somla23 Aug
      • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part 1Mats Kindahl23 Aug
        • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part 1Mats Kindahl23 Aug
        • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part 1Rafal Somla23 Aug
          • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part 1Mats Kindahl23 Aug
    • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part2Rafal Somla23 Aug
      • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part2Mats Kindahl23 Aug
    • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part3Rafal Somla23 Aug
      • Re: bk commit into 5.1 tree (rafal:1.2530) BUG#21842 - part3Mats Kindahl23 Aug