1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Complementary fix for bug #29353: inserting a negative value to a csv table

leads to the table corruption

New Field::store() method implemented to explicitly set thd->count_cuted_fields
before value storing, instead of (incorrectly) setting it in the CSV storage engine.
Thread row counter now properly incremented during check and repair in the CSV engine.
This commit is contained in:
ramil/ram@mysql.com/ramil.myoffice.izhnet.ru
2007-07-03 17:17:58 +05:00
parent 8c26615204
commit ee5403110d
8 changed files with 33 additions and 11 deletions

View File

@ -655,7 +655,8 @@ void **thd_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
int thd_tx_isolation(const MYSQL_THD thd);
char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length,
unsigned int max_query_len);
/* Increments the row counter, see THD::row_count */
void thd_inc_row_count(MYSQL_THD thd);
#ifdef __cplusplus
}

View File

@ -5276,7 +5276,7 @@ drop table t1;
create table t1(a int, b int) engine=csv;
repair table t1;
Table Op Msg_type Msg_text
test.t1 repair Warning Data truncated for column 'a' at row 1
test.t1 repair Warning Data truncated for column 'a' at row 5
test.t1 repair status OK
check table t1;
Table Op Msg_type Msg_text

View File

@ -1360,6 +1360,18 @@ bool Field::send_binary(Protocol *protocol)
}
int Field::store(const char *to, uint length, CHARSET_INFO *cs,
enum_check_fields check_level)
{
int res;
enum_check_fields old_check_level= table->in_use->count_cuted_fields;
table->in_use->count_cuted_fields= check_level;
res= store(to, length, cs);
table->in_use->count_cuted_fields= old_check_level;
return res;
}
my_decimal *Field::val_decimal(my_decimal *decimal)
{
/* This never have to be called */

View File

@ -100,6 +100,8 @@ public:
virtual int store(longlong nr, bool unsigned_val)=0;
virtual int store_decimal(const my_decimal *d)=0;
virtual int store_time(MYSQL_TIME *ltime, timestamp_type t_type);
int store(const char *to, uint length, CHARSET_INFO *cs,
enum_check_fields check_level);
virtual double val_real(void)=0;
virtual longlong val_int(void)=0;
virtual my_decimal *val_decimal(my_decimal *);

View File

@ -494,6 +494,13 @@ enum enum_parsing_place
struct st_table;
class THD;
enum enum_check_fields
{
CHECK_FIELD_IGNORE,
CHECK_FIELD_WARN,
CHECK_FIELD_ERROR_FOR_NULL
};
/* Struct to handle simple linked lists */
typedef struct st_sql_list {

View File

@ -253,6 +253,11 @@ int thd_tx_isolation(const THD *thd)
return (int) thd->variables.tx_isolation;
}
extern "C"
void thd_inc_row_count(THD *thd)
{
thd->row_count++;
}
/*
Dumps a text description of a thread, its security context

View File

@ -39,8 +39,6 @@ enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
DELAY_KEY_WRITE_ALL };
enum enum_check_fields
{ CHECK_FIELD_IGNORE, CHECK_FIELD_WARN, CHECK_FIELD_ERROR_FOR_NULL };
enum enum_mark_columns
{ MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE};

View File

@ -45,8 +45,6 @@ TODO:
#pragma implementation // gcc: Class implementation
#endif
#define MYSQL_SERVER 1
#include "mysql_priv.h"
#include <mysql/plugin.h>
#include "ha_tina.h"
@ -675,7 +673,8 @@ int ha_tina::find_current_row(uchar *buf)
if (bitmap_is_set(table->read_set, (*field)->field_index))
{
if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset()))
if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(),
CHECK_FIELD_WARN))
goto err;
}
}
@ -1002,7 +1001,6 @@ int ha_tina::delete_row(const uchar * buf)
int ha_tina::rnd_init(bool scan)
{
THD *thd= table ? table->in_use : current_thd;
DBUG_ENTER("ha_tina::rnd_init");
/* set buffer to the beginning of the file */
@ -1014,7 +1012,6 @@ int ha_tina::rnd_init(bool scan)
stats.records= 0;
records_is_known= 0;
chain_ptr= chain;
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong values
DBUG_RETURN(0);
}
@ -1298,9 +1295,9 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt)
current_position= next_position= 0;
/* Read the file row-by-row. If everything is ok, repair is not needed. */
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong values
while (!(rc= find_current_row(buf)))
{
thd_inc_row_count(thd);
rows_repaired++;
current_position= next_position;
}
@ -1464,9 +1461,9 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt)
/* set current position to the beginning of the file */
current_position= next_position= 0;
/* Read the file row-by-row. If everything is ok, repair is not needed. */
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong values
while (!(rc= find_current_row(buf)))
{
thd_inc_row_count(thd);
count--;
current_position= next_position;
}