|
|||||||||||
|
Re: [Fwd: How to report duplicate key values in handler::add_index()?]
From: Ingo Strüwing <ingo(at)mysql.com>
Date: Mon Aug 27 2007 - 06:24:41 EDT
Martin Skold, 17.08.2007 16:40:
table->record[0] contains the row data. table->key_info[] contains index information for the existing indexes. table->s->keys tells the array size. key_info does not contain row data or key data. It just points into table->record[0] so that the keys can be constructed from it. handler::add_index() takes a key_info array[0 .. number of indexes to add - 1] and the number of indexes to add. You need to copy the record (with the duplicate key) into table->record[0], and report the array slot number of the add_index() key_info array as the "errkey" in handler::info(). ALTER TABLE, after the call to add_index(), temporarily exchanges the original table->key_info array by the array sent to add_index(). So the duplicate key message should be constructed from the correct key_info. For example a table has 2 indexes. So we have table->key_info[0..1]. These are the original indexes. We want to add four new indexes. add_index() has key_info[0..3]. If the third is a duplicate key and provokes a duplicate key error, copy the offending record into table->record[0]. On handler::info(HA_STATUS_ERRKEY) return errkey=2 (which is the third key from the add_index() key_info array). ALTER TABLE will then exchange the key_info array and table->file->print_error() will construct the duplicate key message from the right key_info slot. At least this was my intention when implementing it. If it does not work this way, please report it as a bug. > Furthermore, is there any better documentation for TABLE than this Unfortunately I don't know about better documentation. I agree with you that write_row_record should be used in THD::binlog_*_row() only. In structs.h we have: /* Bits in form->status */ #define STATUS_NO_RECORD (1+2) /* Record isn't usably */ #define STATUS_GARBAGE 1 #define STATUS_NOT_FOUND 2 /* No record in database when needed */ #define STATUS_NO_PARENT 4 /* Parent record wasn't found */ #define STATUS_NOT_READ 8 /* Record isn't read */ #define STATUS_UPDATED 16 /* Record is updated by formula */ #define STATUS_NULL_ROW 32 /* table->null_row is set */ #define STATUS_DELETED 64 record[1] is used for UPDATE. It contains the old row, while record[0] contains the new row. Tables that cannot be updated may not have record[1]. For safety reasons record[1] would point to the same location as record[0] then.
Regards
-- Ingo Strüwing, Senior Software Developer MySQL GmbH, Dachauer Str. 37, D-80335 München Geschäftsführer: Kaj Arnö - HRB München 162140 -- MySQL Internals Mailing List For list archives: http://lists.mysql.com/internals To unsubscribe: http://lists.mysql.com/internals?unsub=lists@pantek.comReceived on Mon Aug 27 06:25:53 2007 This archive was generated by hypermail 2.1.8 : Sun Oct 07 2007 - 07:59:14 EDT |
||||||||||
|
|||||||||||