~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/replication_services.cc

Merging Jay.

Show diffs side-by-side

added added

removed removed

Lines of Context:
241
241
  {
242
242
    finalizeStatement(*statement, in_session);
243
243
  }
 
244
  else
 
245
    return; /* No data modification occurred inside the transaction */
244
246
  
245
247
  message::Transaction* transaction= getActiveTransaction(in_session);
246
248
 
463
465
      field_metadata= header->add_set_field_metadata();
464
466
      field_metadata->set_name(current_field->field_name);
465
467
      field_metadata->set_type(internalFieldTypeToFieldProtoType(current_field->type()));
466
 
 
 
468
    }
 
469
  }
 
470
}
 
471
void ReplicationServices::updateRecord(Session *in_session,
 
472
                                       Table *in_table, 
 
473
                                       const unsigned char *old_record, 
 
474
                                       const unsigned char *new_record)
 
475
{
 
476
  if (! is_active)
 
477
    return;
 
478
 
 
479
  message::Statement &statement= getUpdateStatement(in_session, in_table, old_record, new_record);
 
480
 
 
481
  message::UpdateData *data= statement.mutable_update_data();
 
482
  data->set_segment_id(1);
 
483
  data->set_end_segment(true);
 
484
  message::UpdateRecord *record= data->add_record();
 
485
 
 
486
  Field *current_field;
 
487
  Field **table_fields= in_table->field;
 
488
  String *string_value= new (in_session->mem_root) String(ReplicationServices::DEFAULT_RECORD_SIZE);
 
489
  string_value->set_charset(system_charset_info);
 
490
 
 
491
  while ((current_field= *table_fields++) != NULL) 
 
492
  {
 
493
    /*
 
494
     * Here, we add the SET field values.  We used to do this in the setUpdateHeader() method, 
 
495
     * but then realized that an UPDATE statement could potentially have different values for
 
496
     * the SET field.  For instance, imagine this SQL scenario:
 
497
     *
 
498
     * CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, count INT NOT NULL);
 
499
     * INSERT INTO t1 (id, counter) VALUES (1,1),(2,2),(3,3);
 
500
     * UPDATE t1 SET counter = counter + 1 WHERE id IN (1,2);
 
501
     *
 
502
     * We will generate two UpdateRecord messages with different set_value byte arrays.
 
503
     *
 
504
     * The below really should be moved into the Field API and Record API.  But for now
 
505
     * we do this crazy pointer fiddling to figure out if the current field
 
506
     * has been updated in the supplied record raw byte pointers.
 
507
     */
 
508
    const unsigned char *old_ptr= (const unsigned char *) old_record + (ptrdiff_t) (current_field->ptr - in_table->record[0]); 
 
509
    const unsigned char *new_ptr= (const unsigned char *) new_record + (ptrdiff_t) (current_field->ptr - in_table->record[0]); 
 
510
 
 
511
    uint32_t field_length= current_field->pack_length(); /** @TODO This isn't always correct...check varchar diffs. */
 
512
 
 
513
    if (memcmp(old_ptr, new_ptr, field_length) != 0)
 
514
    {
467
515
      /* Store the original "read bit" for this field */
468
516
      bool is_read_set= current_field->isReadSet();
469
517
 
479
527
       */
480
528
      current_field->setReadSet(is_read_set);
481
529
 
482
 
      header->add_set_value(string_value->c_ptr());
 
530
      record->add_after_value(string_value->c_ptr());
483
531
      string_value->free();
484
532
    }
485
 
  }
486
 
}
487
 
void ReplicationServices::updateRecord(Session *in_session,
488
 
                                       Table *in_table, 
489
 
                                       const unsigned char *old_record, 
490
 
                                       const unsigned char *new_record)
491
 
{
492
 
  if (! is_active)
493
 
    return;
494
 
 
495
 
  message::Statement &statement= getUpdateStatement(in_session, in_table, old_record, new_record);
496
 
 
497
 
  message::UpdateData *data= statement.mutable_update_data();
498
 
  data->set_segment_id(1);
499
 
  data->set_end_segment(true);
500
 
  message::UpdateRecord *record= data->add_record();
501
 
 
502
 
  Field *current_field;
503
 
  Field **table_fields= in_table->field;
504
 
  String *string_value= new (in_session->mem_root) String(ReplicationServices::DEFAULT_RECORD_SIZE);
505
 
  string_value->set_charset(system_charset_info);
506
 
 
507
 
  while ((current_field= *table_fields++) != NULL) 
508
 
  {
 
533
 
509
534
    /* 
510
535
     * Add the WHERE clause values now...the fields which return true
511
536
     * for isReadSet() are in the WHERE clause.  For tables with no
520
545
       */
521
546
      string_value->free();
522
547
    }
 
548
 
523
549
  }
524
550
}
525
551