~posulliv/drizzle/memcached_applier

« back to all changes in this revision

Viewing changes to drizzled/log_event.cc

  • Committer: Eric Herman
  • Date: 2008-12-06 19:42:46 UTC
  • mto: (656.1.6 devel)
  • mto: This revision was merged to the branch mainline in revision 665.
  • Revision ID: eric@mysql.com-20081206194246-5cdexuu81i366eek
removed trailing whitespace with simple script:

for file in $(find . -name "*.c") $(find . -name "*.cc") $(find . -name "*.h"); do ruby -pe 'gsub(/\s+$/, $/)' < $file > $file.out; mv $file.out $file; done;

Show diffs side-by-side

added added

removed removed

Lines of Context:
134
134
    len= snprintf(slider, buff_end - slider,
135
135
                  _(" %s, Error_code: %d;"), err->msg, err->code);
136
136
  }
137
 
  
 
137
 
138
138
  rli->report(level, session->is_error()? session->main_da.sql_errno() : 0,
139
139
              _("Could not execute %s event on table %s.%s;"
140
140
                "%s handler error %s; "
324
324
  if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
325
325
    return;
326
326
 
327
 
  /* 
 
327
  /*
328
328
     When we are deleting temporary files, we should only remove
329
329
     the files associated with the server id of our server.
330
330
     We don't use event_server_id here because since we've disabled
331
331
     direct binlogging of Create_file/Append_file/Exec_load events
332
 
     we cannot meet Start_log event in the middle of events from one 
 
332
     we cannot meet Start_log event in the middle of events from one
333
333
     LOAD DATA.
334
334
  */
335
335
  p= strncpy(prefbuf, STRING_WITH_LEN("SQL_LOAD-")) + 9;
599
599
    if (debug_not_change_ts_if_art_event == 1
600
600
        && is_artificial_event())
601
601
      debug_not_change_ts_if_art_event= 0;
602
 
    rli->stmt_done(log_pos, 
 
602
    rli->stmt_done(log_pos,
603
603
                   is_artificial_event() &&
604
604
                   debug_not_change_ts_if_art_event > 0 ? 0 : when);
605
605
    if (debug_not_change_ts_if_art_event == 0)
1040
1040
    *error= "Found invalid event in binary log";
1041
1041
    return(0);
1042
1042
  }
1043
 
  return(ev);  
 
1043
  return(ev);
1044
1044
}
1045
1045
 
1046
1046
inline Log_event::enum_skip_reason
1196
1196
    start+= 4;
1197
1197
    }
1198
1198
  */
1199
 
  
 
1199
 
1200
1200
  /* Store length of status variables */
1201
1201
  status_vars_len= (uint) (start-start_of_status);
1202
1202
  assert(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
1220
1220
/**
1221
1221
  The simplest constructor that could possibly work.  This is used for
1222
1222
  creating static objects that have a special meaning and are invisible
1223
 
  to the log.  
 
1223
  to the log.
1224
1224
*/
1225
1225
Query_log_event::Query_log_event()
1226
1226
  :Log_event(), data_buf(0)
1274
1274
    (killed_status_arg == Session::NOT_KILLED) ?
1275
1275
    (session_arg->is_error() ? session_arg->main_da.sql_errno() : 0) :
1276
1276
    (session_arg->killed_errno());
1277
 
  
 
1277
 
1278
1278
  time(&end_time);
1279
1279
  exec_time = (ulong) (end_time  - session_arg->start_time);
1280
1280
  /**
1286
1286
  db_len = (db) ? (uint32_t) strlen(db) : 0;
1287
1287
  if (session_arg->variables.collation_database != session_arg->db_charset)
1288
1288
    charset_database_number= session_arg->variables.collation_database->number;
1289
 
  
 
1289
 
1290
1290
  /*
1291
1291
    If we don't use flags2 for anything else than options contained in
1292
1292
    session_arg->options, it would be more efficient to flags2=session_arg->options
1305
1305
  time_zone_len= 0;
1306
1306
}
1307
1307
 
1308
 
static void copy_str_and_move(const char **src, 
1309
 
                              Log_event::Byte **dst, 
 
1308
static void copy_str_and_move(const char **src,
 
1309
                              Log_event::Byte **dst,
1310
1310
                              uint32_t len)
1311
1311
{
1312
1312
  memcpy(*dst, *src, len);
1355
1355
 
1356
1356
  common_header_len= description_event->common_header_len;
1357
1357
  post_header_len= description_event->post_header_len[event_type-1];
1358
 
  
 
1358
 
1359
1359
  /*
1360
1360
    We test if the event's length is sensible, and if so we compute data_len.
1361
1361
    We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
1362
1362
    We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
1363
1363
  */
1364
1364
  if (event_len < (uint)(common_header_len + post_header_len))
1365
 
    return;                             
 
1365
    return;
1366
1366
  data_len = event_len - (common_header_len + post_header_len);
1367
1367
  buf+= common_header_len;
1368
 
  
 
1368
 
1369
1369
  slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
1370
1370
  exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
1371
1371
  db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
1376
1376
    Depending on the format, we may or not have affected/warnings etc
1377
1377
    The remnent post-header to be parsed has length:
1378
1378
  */
1379
 
  tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN; 
 
1379
  tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
1380
1380
  if (tmp)
1381
1381
  {
1382
1382
    status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
1401
1401
  */
1402
1402
 
1403
1403
  /* variable-part: the status vars; only in MySQL 5.0  */
1404
 
  
 
1404
 
1405
1405
  start= (Log_event::Byte*) (buf+post_header_len);
1406
1406
  end= (const Log_event::Byte*) (start+status_vars_len);
1407
1407
  for (const Log_event::Byte* pos= start; pos < end;)
1428
1428
      pos= (const unsigned char*) end;                         // Break loop
1429
1429
    }
1430
1430
  }
1431
 
  
 
1431
 
1432
1432
  if (!(start= data_buf = (Log_event::Byte*) malloc(catalog_len + 1 +
1433
1433
                                             time_zone_len + 1 +
1434
1434
                                             data_len + 1)))
1459
1459
    my_alloc call above? /sven
1460
1460
  */
1461
1461
 
1462
 
  /* A 2nd variable part; this is common to all versions */ 
 
1462
  /* A 2nd variable part; this is common to all versions */
1463
1463
  memcpy(start, end, data_len);          // Copy db and query
1464
1464
  start[data_len]= '\0';              // End query with \0 (For safetly)
1465
1465
  db= (char *)start;
1591
1591
      }
1592
1592
      else
1593
1593
        session->variables.collation_database= session->db_charset;
1594
 
      
 
1594
 
1595
1595
      /* Execute the query (note that we bypass dispatch_command()) */
1596
1596
      const char* found_semicolon= NULL;
1597
1597
      mysql_parse(session, session->query, session->query_length, &found_semicolon);
1648
1648
      session->is_slave_error= 1;
1649
1649
    }
1650
1650
    /*
1651
 
      If we get the same error code as expected, or they should be ignored. 
 
1651
      If we get the same error code as expected, or they should be ignored.
1652
1652
    */
1653
1653
    else if (expected_error == actual_error ||
1654
1654
             ignored_error_code(actual_error))
1698
1698
    Probably we have set session->query, session->db, session->catalog to point to places
1699
1699
    in the data_buf of this event. Now the event is going to be deleted
1700
1700
    probably, so data_buf will be freed, so the session->... listed above will be
1701
 
    pointers to freed memory. 
 
1701
    pointers to freed memory.
1702
1702
    So we must set them to 0, so that those bad pointers values are not later
1703
1703
    used. Note that "cleanup" queries like automatic DROP TEMPORARY Table
1704
1704
    don't suffer from these assignments to 0 as DROP TEMPORARY
1709
1709
  session->query= 0;                    // just to be sure
1710
1710
  session->query_length= 0;
1711
1711
  pthread_mutex_unlock(&LOCK_thread_count);
1712
 
  close_thread_tables(session);      
 
1712
  close_thread_tables(session);
1713
1713
  session->first_successful_insert_id_in_prev_stmt= 0;
1714
1714
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
1715
1715
  return session->is_slave_error;
2304
2304
  {
2305
2305
    pos= my_stpcpy(pos, " IGNORE ");
2306
2306
    pos= int64_t10_to_str((int64_t) skip_lines, pos, 10);
2307
 
    pos= my_stpcpy(pos," LINES ");    
 
2307
    pos= my_stpcpy(pos," LINES ");
2308
2308
  }
2309
2309
 
2310
2310
  if (num_fields)
2417
2417
  sql_ex.escaped_len = (uint8_t) ex->escaped->length();
2418
2418
  sql_ex.opt_flags = 0;
2419
2419
  sql_ex.cached_new_format = -1;
2420
 
    
 
2420
 
2421
2421
  if (ex->dumpfile)
2422
2422
    sql_ex.opt_flags|= DUMPFILE_FLAG;
2423
2423
  if (ex->opt_enclosed)
2431
2431
    break;
2432
2432
  case DUP_UPDATE:                              // Impossible here
2433
2433
  case DUP_ERROR:
2434
 
    break;      
 
2434
    break;
2435
2435
  }
2436
2436
  if (ignore)
2437
2437
    sql_ex.opt_flags|= IGNORE_FLAG;
2446
2446
    sql_ex.empty_flags |= LINE_START_EMPTY;
2447
2447
  if (!ex->escaped->length())
2448
2448
    sql_ex.empty_flags |= ESCAPED_EMPTY;
2449
 
    
 
2449
 
2450
2450
  skip_lines = ex->skip_lines;
2451
2451
 
2452
2452
  List_iterator<Item> li(fields_arg);
2485
2485
  if (event_len)
2486
2486
    copy_log_event(buf, event_len,
2487
2487
                   ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
2488
 
                    LOAD_HEADER_LEN + 
 
2488
                    LOAD_HEADER_LEN +
2489
2489
                    description_event->common_header_len :
2490
2490
                    LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
2491
2491
                   description_event);
2512
2512
  table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
2513
2513
  db_len = (uint)data_head[L_DB_LEN_OFFSET];
2514
2514
  num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
2515
 
          
 
2515
 
2516
2516
  if ((int) event_len < body_offset)
2517
2517
    return(1);
2518
2518
  /*
2523
2523
                                        buf_end,
2524
2524
                                        buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
2525
2525
    return(1);
2526
 
  
 
2526
 
2527
2527
  data_len = event_len - body_offset;
2528
2528
  if (num_fields > data_len) // simple sanity check against corruption
2529
2529
    return(1);
2545
2545
  Load_log_event::set_fields()
2546
2546
 
2547
2547
  @note
2548
 
    This function can not use the member variable 
 
2548
    This function can not use the member variable
2549
2549
    for the database, since LOAD DATA INFILE on the slave
2550
2550
    can be for a different database than the current one.
2551
2551
    This is the reason for the affected_db argument to this method.
2552
2552
*/
2553
2553
 
2554
 
void Load_log_event::set_fields(const char* affected_db, 
 
2554
void Load_log_event::set_fields(const char* affected_db,
2555
2555
                                List<Item> &field_list,
2556
2556
                                Name_resolution_context *context)
2557
2557
{
2622
2622
    */
2623
2623
    const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
2624
2624
  }
2625
 
 
 
2625
 
2626
2626
   /*
2627
2627
    We test replicate_*_db rules. Note that we have already prepared
2628
2628
    the file to load, even if we are going to ignore and delete it
2665
2665
    tables.lock_type = TL_WRITE;
2666
2666
    tables.updating= 1;
2667
2667
 
2668
 
    // the table will be opened in mysql_load    
 
2668
    // the table will be opened in mysql_load
2669
2669
    {
2670
2670
      char llbuff[22];
2671
2671
      char *end;
2774
2774
                            "log position %s in log '%s' produced %ld "
2775
2775
                            "warning(s). Default database: '%s'"),
2776
2776
                          (char*) table_name,
2777
 
                          llstr(log_pos,llbuff), RPL_LOG_NAME, 
 
2777
                          llstr(log_pos,llbuff), RPL_LOG_NAME,
2778
2778
                          (ulong) session->cuted_fields,
2779
2779
                          print_slave_db_safe(session->db));
2780
2780
      }
2794
2794
  }
2795
2795
 
2796
2796
error:
2797
 
  session->net.vio = 0; 
 
2797
  session->net.vio = 0;
2798
2798
  const char *remember_db= session->db;
2799
2799
  pthread_mutex_lock(&LOCK_thread_count);
2800
2800
  session->catalog= 0;
2897
2897
  buf += header_size;
2898
2898
  pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
2899
2899
  ident_len = (uint)(event_len -
2900
 
                     (header_size+post_header_len)); 
2901
 
  ident_offset = post_header_len; 
 
2900
                     (header_size+post_header_len));
 
2901
  ident_offset = post_header_len;
2902
2902
  set_if_smaller(ident_len,FN_REFLEN-1);
2903
2903
  new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
2904
2904
  return;
3271
3271
    return;
3272
3272
  if (description_event->binlog_version!=1)
3273
3273
  {
3274
 
    file_id= uint4korr(buf + 
 
3274
    file_id= uint4korr(buf +
3275
3275
                       header_len +
3276
3276
                       load_header_len + CF_FILE_ID_OFFSET);
3277
3277
    /*
3283
3283
      as these Load events are not changed between 4.0 and 5.0 (as logging of
3284
3284
      LOAD DATA INFILE does not use Load_log_event in 5.0).
3285
3285
 
3286
 
      The + 1 is for \0 terminating fname  
 
3286
      The + 1 is for \0 terminating fname
3287
3287
    */
3288
3288
    block_offset= (description_event->common_header_len +
3289
3289
                   Load_log_event::get_data_size() +
3349
3349
                fname_buf);
3350
3350
    goto err;
3351
3351
  }
3352
 
  
 
3352
 
3353
3353
  // a trick to avoid allocating another buffer
3354
3354
  fname= fname_buf;
3355
3355
  fname_len= (uint) (my_stpcpy(ext, ".data") - fname);
3421
3421
                                               const Format_description_log_event* description_event)
3422
3422
  :Log_event(buf, description_event),block(0)
3423
3423
{
3424
 
  uint8_t common_header_len= description_event->common_header_len; 
 
3424
  uint8_t common_header_len= description_event->common_header_len;
3425
3425
  uint8_t append_block_header_len=
3426
3426
    description_event->post_header_len[APPEND_BLOCK_EVENT-1];
3427
3427
  uint32_t total_header_len= common_header_len+append_block_header_len;
3606
3606
  :Log_event(session_arg, 0, using_trans), file_id(session_arg->file_id), db(db_arg)
3607
3607
{
3608
3608
}
3609
 
  
 
3609
 
3610
3610
 
3611
3611
/*
3612
3612
  Execute_load_log_event ctor
3632
3632
{
3633
3633
  unsigned char buf[EXEC_LOAD_HEADER_LEN];
3634
3634
  int4store(buf + EL_FILE_ID_OFFSET, file_id);
3635
 
  return (write_header(file, sizeof(buf)) || 
 
3635
  return (write_header(file, sizeof(buf)) ||
3636
3636
          my_b_safe_write(file, buf, sizeof(buf)));
3637
3637
}
3638
3638
 
3696
3696
  */
3697
3697
 
3698
3698
  const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
3699
 
  if (lev->do_apply_event(0,rli,1)) 
 
3699
  if (lev->do_apply_event(0,rli,1))
3700
3700
  {
3701
3701
    /*
3702
3702
      We want to indicate the name of the file that could not be loaded
4014
4014
    m_table(tbl_arg),
4015
4015
    m_table_id(tid),
4016
4016
    m_width(tbl_arg ? tbl_arg->s->fields : 1),
4017
 
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) 
 
4017
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0)
4018
4018
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
4019
4019
{
4020
4020
  /*
4164
4164
    data_size+= no_bytes_in_map(&m_cols_ai);
4165
4165
 
4166
4166
  data_size+= (m_rows_cur - m_rows_buf);
4167
 
  return data_size; 
 
4167
  return data_size;
4168
4168
}
4169
4169
 
4170
4170
 
4196
4196
  {
4197
4197
    size_t const block_size= 1024;
4198
4198
    my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf;
4199
 
    my_ptrdiff_t const new_alloc= 
 
4199
    my_ptrdiff_t const new_alloc=
4200
4200
        block_size * ((cur_size + length + block_size - 1) / block_size);
4201
4201
 
4202
4202
    unsigned char* const new_buf= (unsigned char*)my_realloc((unsigned char*)m_rows_buf, (uint) new_alloc,
4403
4403
    }
4404
4404
  }
4405
4405
 
4406
 
  Table* 
4407
 
    table= 
 
4406
  Table*
 
4407
    table=
4408
4408
    m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
4409
4409
 
4410
4410
  if (table)
4438
4438
        session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
4439
4439
    else
4440
4440
        session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
4441
 
    
 
4441
 
4442
4442
    if (slave_allow_batching)
4443
4443
      session->options|= OPTION_ALLOW_BATCH;
4444
4444
    else
4445
4445
      session->options&= ~OPTION_ALLOW_BATCH;
4446
 
    
 
4446
 
4447
4447
    /* A small test to verify that objects have consistent types */
4448
4448
    assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
4449
4449
 
4461
4461
     if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
4462
4462
      set_flags(COMPLETE_ROWS_F);
4463
4463
 
4464
 
    /* 
 
4464
    /*
4465
4465
      Set tables write and read sets.
4466
 
      
 
4466
 
4467
4467
      Read_set contains all slave columns (in case we are going to fetch
4468
4468
      a complete record from slave)
4469
 
      
4470
 
      Write_set equals the m_cols bitmap sent from master but it can be 
4471
 
      longer if slave has extra columns. 
4472
 
     */ 
 
4469
 
 
4470
      Write_set equals the m_cols bitmap sent from master but it can be
 
4471
      longer if slave has extra columns.
 
4472
     */
4473
4473
 
4474
4474
    bitmap_set_all(table->read_set);
4475
4475
    bitmap_set_all(table->write_set);
4478
4478
 
4479
4479
    this->slave_exec_mode= slave_exec_mode_options; // fix the mode
4480
4480
 
4481
 
    // Do event specific preparations 
 
4481
    // Do event specific preparations
4482
4482
    error= do_before_row_operations(rli);
4483
4483
 
4484
4484
    // row processing loop
4500
4500
      /*
4501
4501
        The following list of "idempotent" errors
4502
4502
        means that an error from the list might happen
4503
 
        because of idempotent (more than once) 
 
4503
        because of idempotent (more than once)
4504
4504
        applying of a binlog file.
4505
4505
        Notice, that binlog has a  ddl operation its
4506
4506
        second applying may cause
4507
4507
 
4508
4508
        case HA_ERR_TABLE_DEF_CHANGED:
4509
4509
        case HA_ERR_CANNOT_ADD_FOREIGN:
4510
 
        
 
4510
 
4511
4511
        which are not included into to the list.
4512
4512
      */
4513
4513
      case HA_ERR_RECORD_CHANGED:
4528
4528
          error= 0;
4529
4529
        }
4530
4530
        break;
4531
 
        
 
4531
 
4532
4532
      default:
4533
4533
        session->is_slave_error= 1;
4534
4534
        break;
4537
4537
      /*
4538
4538
       If m_curr_row_end  was not set during event execution (e.g., because
4539
4539
       of errors) we can't proceed to the next row. If the error is transient
4540
 
       (i.e., error==0 at this point) we must call unpack_current_row() to set 
 
4540
       (i.e., error==0 at this point) we must call unpack_current_row() to set
4541
4541
       m_curr_row_end.
4542
 
      */ 
 
4542
      */
4543
4543
      if (!m_curr_row_end && !error)
4544
4544
        unpack_current_row(rli, &m_cols);
4545
 
  
 
4545
 
4546
4546
      // at this moment m_curr_row_end should be set
4547
 
      assert(error || m_curr_row_end != NULL); 
 
4547
      assert(error || m_curr_row_end != NULL);
4548
4548
      assert(error || m_curr_row < m_curr_row_end);
4549
4549
      assert(error || m_curr_row_end <= m_rows_end);
4550
 
  
 
4550
 
4551
4551
      m_curr_row= m_curr_row_end;
4552
 
 
 
4552
 
4553
4553
    } // row processing loop
4554
4554
 
4555
4555
    error= do_after_row_operations(rli, error);
4567
4567
    const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4568
4568
  /* reset OPTION_ALLOW_BATCH as not affect later events */
4569
4569
  session->options&= ~OPTION_ALLOW_BATCH;
4570
 
  
 
4570
 
4571
4571
  if (error)
4572
4572
  {                     /* error has occured during the transaction */
4573
4573
    slave_rows_error_report(ERROR_LEVEL, error, rli, session, table,
4772
4772
 
4773
4773
/**
4774
4774
  @page How replication of field metadata works.
4775
 
  
4776
 
  When a table map is created, the master first calls 
4777
 
  Table_map_log_event::save_field_metadata() which calculates how many 
4778
 
  values will be in the field metadata. Only those fields that require the 
4779
 
  extra data are added. The method also loops through all of the fields in 
 
4775
 
 
4776
  When a table map is created, the master first calls
 
4777
  Table_map_log_event::save_field_metadata() which calculates how many
 
4778
  values will be in the field metadata. Only those fields that require the
 
4779
  extra data are added. The method also loops through all of the fields in
4780
4780
  the table calling the method Field::save_field_metadata() which returns the
4781
4781
  values for the field that will be saved in the metadata and replicated to
4782
4782
  the slave. Once all fields have been processed, the table map is written to
4783
4783
  the binlog adding the size of the field metadata and the field metadata to
4784
4784
  the end of the body of the table map.
4785
4785
 
4786
 
  When a table map is read on the slave, the field metadata is read from the 
4787
 
  table map and passed to the table_def class constructor which saves the 
4788
 
  field metadata from the table map into an array based on the type of the 
4789
 
  field. Field metadata values not present (those fields that do not use extra 
4790
 
  data) in the table map are initialized as zero (0). The array size is the 
 
4786
  When a table map is read on the slave, the field metadata is read from the
 
4787
  table map and passed to the table_def class constructor which saves the
 
4788
  field metadata from the table map into an array based on the type of the
 
4789
  field. Field metadata values not present (those fields that do not use extra
 
4790
  data) in the table map are initialized as zero (0). The array size is the
4791
4791
  same as the columns for the table on the slave.
4792
4792
 
4793
 
  Additionally, values saved for field metadata on the master are saved as a 
 
4793
  Additionally, values saved for field metadata on the master are saved as a
4794
4794
  string of bytes (unsigned char) in the binlog. A field may require 1 or more bytes
4795
 
  to store the information. In cases where values require multiple bytes 
4796
 
  (e.g. values > 255), the endian-safe methods are used to properly encode 
 
4795
  to store the information. In cases where values require multiple bytes
 
4796
  (e.g. values > 255), the endian-safe methods are used to properly encode
4797
4797
  the values on the master and decode them on the slave. When the field
4798
4798
  metadata values are captured on the slave, they are stored in an array of
4799
4799
  type uint16_t. This allows the least number of casts to prevent casting bugs
4800
4800
  when the field metadata is used in comparisons of field attributes. When
4801
4801
  the field metadata is used for calculating addresses in pointer math, the
4802
 
  type used is uint32_t. 
 
4802
  type used is uint32_t.
4803
4803
*/
4804
4804
 
4805
4805
/**
4807
4807
  The metadata saved depends on the type of the field. Some fields
4808
4808
  store a single byte for pack_length() while others store two bytes
4809
4809
  for field_length (max length).
4810
 
  
 
4810
 
4811
4811
  @retval  0  Ok.
4812
4812
 
4813
4813
  @todo
4814
4814
  We may want to consider changing the encoding of the information.
4815
 
  Currently, the code attempts to minimize the number of bytes written to 
4816
 
  the tablemap. There are at least two other alternatives; 1) using 
 
4815
  Currently, the code attempts to minimize the number of bytes written to
 
4816
  the tablemap. There are at least two other alternatives; 1) using
4817
4817
  net_store_length() to store the data allowing it to choose the number of
4818
 
  bytes that are appropriate thereby making the code much easier to 
 
4818
  bytes that are appropriate thereby making the code much easier to
4819
4819
  maintain (only 1 place to change the encoding), or 2) use a fixed number
4820
4820
  of bytes for each field. The problem with option 1 is that net_store_length()
4821
4821
  will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
4824
4824
  encoded using 2 parts (e.g., pack_length, field_length) will be numerically
4825
4825
  > 250 therefore will use 3 bytes for eah value. The problem with option 2
4826
4826
  is less wasteful for space but does waste 1 byte for every field that does
4827
 
  not encode 2 parts. 
 
4827
  not encode 2 parts.
4828
4828
*/
4829
4829
int Table_map_log_event::save_field_metadata()
4830
4830
{
4908
4908
    plus one or two bytes for number of elements in the field metadata array.
4909
4909
  */
4910
4910
  if (m_field_metadata_size > 255)
4911
 
    m_data_size+= m_field_metadata_size + 2; 
 
4911
    m_data_size+= m_field_metadata_size + 2;
4912
4912
  else
4913
 
    m_data_size+= m_field_metadata_size + 1; 
 
4913
    m_data_size+= m_field_metadata_size + 1;
4914
4914
 
4915
4915
  memset(m_null_bits, 0, num_null_bytes);
4916
4916
  for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
5125
5125
      inside Relay_log_info::clear_tables_to_lock() by calling the
5126
5126
      table_def destructor explicitly.
5127
5127
    */
5128
 
    new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt, 
 
5128
    new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt,
5129
5129
         m_field_metadata, m_field_metadata_size, m_null_bits);
5130
5130
    table_list->m_tabledef_valid= true;
5131
5131
 
5244
5244
{
5245
5245
}
5246
5246
 
5247
 
int 
 
5247
int
5248
5248
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
5249
5249
{
5250
5250
  int error= 0;
5260
5260
      when writing rows, that is: new rows replace old rows.  We need to
5261
5261
      inform the storage engine that it should use this behaviour.
5262
5262
    */
5263
 
    
 
5263
 
5264
5264
    /* Tell the storage engine that we are using REPLACE semantics. */
5265
5265
    session->lex->duplicates= DUP_REPLACE;
5266
 
    
 
5266
 
5267
5267
    /*
5268
5268
      Pretend we're executing a REPLACE command: this is needed for
5269
5269
      InnoDB since it is not (properly) checking the
5270
5270
      lex->duplicates flag.
5271
5271
    */
5272
5272
    session->lex->sql_command= SQLCOM_REPLACE;
5273
 
    /* 
 
5273
    /*
5274
5274
       Do not raise the error flag in case of hitting to an unique attribute
5275
5275
    */
5276
5276
    m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5297
5297
  return error;
5298
5298
}
5299
5299
 
5300
 
int 
 
5300
int
5301
5301
Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
5302
5302
                                              int error)
5303
5303
{
5307
5307
    m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
5308
5308
    m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
5309
5309
    /*
5310
 
      resetting the extra with 
5311
 
      table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY); 
 
5310
      resetting the extra with
 
5311
      table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
5312
5312
      fires bug#27077
5313
5313
      explanation: file->reset() performs this duty
5314
5314
      ultimately. Still todo: fix
5363
5363
  Write the current row into event's table.
5364
5364
 
5365
5365
  The row is located in the row buffer, pointed by @c m_curr_row member.
5366
 
  Number of columns of the row is stored in @c m_width member (it can be 
5367
 
  different from the number of columns in the table to which we insert). 
5368
 
  Bitmap @c m_cols indicates which columns are present in the row. It is assumed 
 
5366
  Number of columns of the row is stored in @c m_width member (it can be
 
5367
  different from the number of columns in the table to which we insert).
 
5368
  Bitmap @c m_cols indicates which columns are present in the row. It is assumed
5369
5369
  that event's table is already open and pointed by @c m_table.
5370
5370
 
5371
 
  If the same record already exists in the table it can be either overwritten 
5372
 
  or an error is reported depending on the value of @c overwrite flag 
 
5371
  If the same record already exists in the table it can be either overwritten
 
5372
  or an error is reported depending on the value of @c overwrite flag
5373
5373
  (error reporting not yet implemented). Note that the matching record can be
5374
5374
  different from the row we insert if we use primary keys to identify records in
5375
5375
  the table.
5376
5376
 
5377
 
  The row to be inserted can contain values only for selected columns. The 
5378
 
  missing columns are filled with default values using @c prepare_record() 
 
5377
  The row to be inserted can contain values only for selected columns. The
 
5378
  missing columns are filled with default values using @c prepare_record()
5379
5379
  function. If a matching record is found in the table and @c overwritte is
5380
5380
  true, the missing columns are taken from it.
5381
5381
 
5382
5382
  @param  rli   Relay log info (needed for row unpacking).
5383
 
  @param  overwrite  
5384
 
                Shall we overwrite if the row already exists or signal 
 
5383
  @param  overwrite
 
5384
                Shall we overwrite if the row already exists or signal
5385
5385
                error (currently ignored).
5386
5386
 
5387
5387
  @returns Error code on failure, 0 on success.
5388
5388
 
5389
5389
  This method, if successful, sets @c m_curr_row_end pointer to point at the
5390
 
  next row in the rows buffer. This is done when unpacking the row to be 
 
5390
  next row in the rows buffer. This is done when unpacking the row to be
5391
5391
  inserted.
5392
5392
 
5393
 
  @note If a matching record is found, it is either updated using 
 
5393
  @note If a matching record is found, it is either updated using
5394
5394
  @c ha_update_row() or first deleted and then new record written.
5395
 
*/ 
 
5395
*/
5396
5396
 
5397
5397
int
5398
5398
Rows_log_event::write_row(const Relay_log_info *const rli,
5419
5419
  */
5420
5420
  if ((error= prepare_record(table, &m_cols, m_width, true)))
5421
5421
    return(error);
5422
 
  
 
5422
 
5423
5423
  /* unpack row into table->record[0] */
5424
5424
  error= unpack_current_row(rli, &m_cols);
5425
5425
 
5426
5426
  // Temporary fix to find out why it fails [/Matz]
5427
5427
  memcpy(m_table->write_set->bitmap, m_cols.bitmap, (m_table->write_set->n_bits + 7) / 8);
5428
5428
 
5429
 
  /* 
 
5429
  /*
5430
5430
    Try to write record. If a corresponding record already exists in the table,
5431
5431
    we try to change it using ha_update_row() if possible. Otherwise we delete
5432
 
    it and repeat the whole process again. 
 
5432
    it and repeat the whole process again.
5433
5433
 
5434
 
    TODO: Add safety measures against infinite looping. 
 
5434
    TODO: Add safety measures against infinite looping.
5435
5435
   */
5436
5436
 
5437
5437
  while ((error= table->file->ha_write_row(table->record[0])))
5512
5512
     */
5513
5513
 
5514
5514
    /*
5515
 
      If row is incomplete we will use the record found to fill 
5516
 
      missing columns.  
 
5515
      If row is incomplete we will use the record found to fill
 
5516
      missing columns.
5517
5517
    */
5518
5518
    if (!get_flags(COMPLETE_ROWS_F))
5519
5519
    {
5542
5542
      error=table->file->ha_update_row(table->record[1],
5543
5543
                                       table->record[0]);
5544
5544
      switch (error) {
5545
 
                
 
5545
 
5546
5546
      case HA_ERR_RECORD_IS_THE_SAME:
5547
5547
        error= 0;
5548
 
      
 
5548
 
5549
5549
      case 0:
5550
5550
        break;
5551
 
        
5552
 
      default:    
 
5551
 
 
5552
      default:
5553
5553
        table->file->print_error(error, MYF(0));
5554
5554
      }
5555
 
      
 
5555
 
5556
5556
      return(error);
5557
5557
    }
5558
5558
    else
5584
5584
}
5585
5585
 
5586
5586
 
5587
 
int 
 
5587
int
5588
5588
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
5589
5589
{
5590
5590
  assert(m_table != NULL);
5591
5591
  int error=
5592
5592
    write_row(rli,        /* if 1 then overwrite */
5593
5593
              bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
5594
 
    
 
5594
 
5595
5595
  if (error && !session->is_error())
5596
5596
  {
5597
5597
    assert(0);
5598
5598
    my_error(ER_UNKNOWN_ERROR, MYF(0));
5599
5599
  }
5600
 
  
5601
 
  return error; 
 
5600
 
 
5601
  return error;
5602
5602
}
5603
5603
 
5604
5604
 
5686
5686
/**
5687
5687
  Locate the current row in event's table.
5688
5688
 
5689
 
  The current row is pointed by @c m_curr_row. Member @c m_width tells how many 
5690
 
  columns are there in the row (this can be differnet from the number of columns 
5691
 
  in the table). It is assumed that event's table is already open and pointed 
 
5689
  The current row is pointed by @c m_curr_row. Member @c m_width tells how many
 
5690
  columns are there in the row (this can be differnet from the number of columns
 
5691
  in the table). It is assumed that event's table is already open and pointed
5692
5692
  by @c m_table.
5693
5693
 
5694
 
  If a corresponding record is found in the table it is stored in 
5695
 
  @c m_table->record[0]. Note that when record is located based on a primary 
 
5694
  If a corresponding record is found in the table it is stored in
 
5695
  @c m_table->record[0]. Note that when record is located based on a primary
5696
5696
  key, it is possible that the record found differs from the row being located.
5697
5697
 
5698
 
  If no key is specified or table does not have keys, a table scan is used to 
 
5698
  If no key is specified or table does not have keys, a table scan is used to
5699
5699
  find the row. In that case the row should be complete and contain values for
5700
 
  all columns. However, it can still be shorter than the table, i.e. the table 
5701
 
  can contain extra columns not present in the row. It is also possible that 
5702
 
  the table has fewer columns than the row being located. 
5703
 
 
5704
 
  @returns Error code on failure, 0 on success. 
5705
 
  
5706
 
  @post In case of success @c m_table->record[0] contains the record found. 
 
5700
  all columns. However, it can still be shorter than the table, i.e. the table
 
5701
  can contain extra columns not present in the row. It is also possible that
 
5702
  the table has fewer columns than the row being located.
 
5703
 
 
5704
  @returns Error code on failure, 0 on success.
 
5705
 
 
5706
  @post In case of success @c m_table->record[0] contains the record found.
5707
5707
  Also, the internal "cursor" of the table is positioned at the record found.
5708
5708
 
5709
5709
  @note If the engine allows random access of the records, a combination of
5710
 
  @c position() and @c rnd_pos() will be used. 
 
5710
  @c position() and @c rnd_pos() will be used.
5711
5711
 */
5712
5712
 
5713
5713
int Rows_log_event::find_row(const Relay_log_info *rli)
5718
5718
  int error;
5719
5719
 
5720
5720
  /* unpack row - missing fields get default values */
5721
 
  prepare_record(table, &m_cols, m_width, false/* don't check errors */); 
 
5721
  prepare_record(table, &m_cols, m_width, false/* don't check errors */);
5722
5722
  error= unpack_current_row(rli, &m_cols);
5723
5723
 
5724
5724
  // Temporary fix to find out why it fails [/Matz]
5755
5755
  }
5756
5756
 
5757
5757
  // We can't use position() - try other methods.
5758
 
  
 
5758
 
5759
5759
  /*
5760
 
    Save copy of the record in table->record[1]. It might be needed 
 
5760
    Save copy of the record in table->record[1]. It might be needed
5761
5761
    later if linear search is used to find exact match.
5762
 
   */ 
5763
 
  store_record(table,record[1]);    
 
5762
   */
 
5763
  store_record(table,record[1]);
5764
5764
 
5765
5765
  if (table->s->keys > 0)
5766
5766
  {
5785
5785
    my_ptrdiff_t const pos=
5786
5786
      table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
5787
5787
    table->record[0][pos]= 0xFF;
5788
 
    
5789
 
    if ((error= table->file->index_read_map(table->record[0], m_key, 
 
5788
 
 
5789
    if ((error= table->file->index_read_map(table->record[0], m_key,
5790
5790
                                            HA_WHOLE_KEY,
5791
5791
                                            HA_READ_KEY_EXACT)))
5792
5792
    {
5817
5817
 
5818
5818
    /*
5819
5819
      In case key is not unique, we still have to iterate over records found
5820
 
      and find the one which is identical to the row given. A copy of the 
 
5820
      and find the one which is identical to the row given. A copy of the
5821
5821
      record we are looking for is stored in record[1].
5822
 
     */ 
 
5822
     */
5823
5823
    while (record_compare(table))
5824
5824
    {
5825
5825
      /*
5884
5884
      }
5885
5885
    }
5886
5886
    while (restart_count < 2 && record_compare(table));
5887
 
    
5888
 
    /* 
5889
 
      Note: above record_compare will take into accout all record fields 
 
5887
 
 
5888
    /*
 
5889
      Note: above record_compare will take into accout all record fields
5890
5890
      which might be incorrect in case a partial row was given in the event
5891
5891
     */
5892
5892
    table->file->ha_rnd_end();
5925
5925
}
5926
5926
 
5927
5927
 
5928
 
int 
 
5928
int
5929
5929
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
5930
5930
{
5931
5931
  if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
5948
5948
  return 0;
5949
5949
}
5950
5950
 
5951
 
int 
5952
 
Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
 
5951
int
 
5952
Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
5953
5953
                                               int error)
5954
5954
{
5955
5955
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
5965
5965
  int error;
5966
5966
  assert(m_table != NULL);
5967
5967
 
5968
 
  if (!(error= find_row(rli))) 
5969
 
  { 
 
5968
  if (!(error= find_row(rli)))
 
5969
  {
5970
5970
    /*
5971
5971
      Delete the record found, located in record[0]
5972
5972
    */
6029
6029
}
6030
6030
 
6031
6031
 
6032
 
int 
 
6032
int
6033
6033
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6034
6034
{
6035
6035
  if (m_table->s->keys > 0)
6045
6045
  return 0;
6046
6046
}
6047
6047
 
6048
 
int 
6049
 
Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
 
6048
int
 
6049
Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
6050
6050
                                               int error)
6051
6051
{
6052
6052
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6057
6057
  return error;
6058
6058
}
6059
6059
 
6060
 
int 
 
6060
int
6061
6061
Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
6062
6062
{
6063
6063
  assert(m_table != NULL);
6064
6064
 
6065
 
  int error= find_row(rli); 
 
6065
  int error= find_row(rli);
6066
6066
  if (error)
6067
6067
  {
6068
6068
    /*