summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/csv.result31
-rw-r--r--mysql-test/t/csv.test25
-rw-r--r--storage/csv/ha_tina.cc70
3 files changed, 92 insertions, 34 deletions
diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result
index 34dc1cb5b2e..e7cdd612a25 100644
--- a/mysql-test/r/csv.result
+++ b/mysql-test/r/csv.result
@@ -5261,3 +5261,34 @@ CREATE TABLE `bug21328` (
insert into bug21328 values (1,NULL,NULL);
alter table bug21328 engine=myisam;
drop table bug21328;
+create table t1(a int) engine=csv;
+insert into t1 values(-1), (-123.34), (2), (-23);
+select * from t1;
+a
+-1
+-123
+2
+-23
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+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 status OK
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+select * from t1;
+a b
+1 0
+-200 1
+-1 -1
+-1 -100
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+End of 5.1 tests
diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test
index c7c7f3e13ab..6d24b38ee10 100644
--- a/mysql-test/t/csv.test
+++ b/mysql-test/t/csv.test
@@ -1674,3 +1674,28 @@ CREATE TABLE `bug21328` (
insert into bug21328 values (1,NULL,NULL);
alter table bug21328 engine=myisam;
drop table bug21328;
+
+#
+# Bug #29353: negative values
+#
+create table t1(a int) engine=csv;
+insert into t1 values(-1), (-123.34), (2), (-23);
+select * from t1;
+check table t1;
+drop table t1;
+
+create table t1(a int, b int) engine=csv;
+--write_file $MYSQLTEST_VARDIR/master-data/test/t1.CSV
+1, 1E-2
+-2E2, .9
+-10E-1, -.9
+-1, -100.1
+1a, -2b
+EOF
+repair table t1;
+check table t1;
+select * from t1;
+check table t1;
+drop table t1;
+
+--echo End of 5.1 tests
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index 6de153c82d7..239d47890ed 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -45,11 +45,12 @@ TODO:
#pragma implementation // gcc: Class implementation
#endif
-#include "mysql_priv.h"
+#define MYSQL_SERVER 1
+#include "mysql_priv.h"
+#include <mysql/plugin.h>
#include "ha_tina.h"
-#include <mysql/plugin.h>
/*
uchar + uchar + ulonglong + ulonglong + ulonglong + ulonglong + uchar
@@ -609,37 +610,41 @@ int ha_tina::find_current_row(uchar *buf)
for (Field **field=table->field ; *field ; field++)
{
+ char curr_char;
+
buffer.length(0);
- if (curr_offset < end_offset &&
- file_buff->get_value(curr_offset) == '"')
+ if (curr_offset >= end_offset)
+ goto err;
+ curr_char= file_buff->get_value(curr_offset);
+ if (curr_char == '"')
{
curr_offset++; // Incrementpast the first quote
- for(;curr_offset < end_offset; curr_offset++)
+ for(; curr_offset < end_offset; curr_offset++)
{
+ curr_char= file_buff->get_value(curr_offset);
// Need to convert line feeds!
- if (file_buff->get_value(curr_offset) == '"' &&
- ((file_buff->get_value(curr_offset + 1) == ',') ||
- (curr_offset == end_offset -1 )))
+ if (curr_char == '"' &&
+ (curr_offset == end_offset - 1 ||
+ file_buff->get_value(curr_offset + 1) == ','))
{
curr_offset+= 2; // Move past the , and the "
break;
}
- if (file_buff->get_value(curr_offset) == '\\' &&
- curr_offset != (end_offset - 1))
+ if (curr_char == '\\' && curr_offset != (end_offset - 1))
{
curr_offset++;
- if (file_buff->get_value(curr_offset) == 'r')
+ curr_char= file_buff->get_value(curr_offset);
+ if (curr_char == 'r')
buffer.append('\r');
- else if (file_buff->get_value(curr_offset) == 'n' )
+ else if (curr_char == 'n' )
buffer.append('\n');
- else if ((file_buff->get_value(curr_offset) == '\\') ||
- (file_buff->get_value(curr_offset) == '"'))
- buffer.append(file_buff->get_value(curr_offset));
+ else if (curr_char == '\\' || curr_char == '"')
+ buffer.append(curr_char);
else /* This could only happed with an externally created file */
{
buffer.append('\\');
- buffer.append(file_buff->get_value(curr_offset));
+ buffer.append(curr_char);
}
}
else // ordinary symbol
@@ -650,36 +655,29 @@ int ha_tina::find_current_row(uchar *buf)
*/
if (curr_offset == end_offset - 1)
goto err;
- buffer.append(file_buff->get_value(curr_offset));
+ buffer.append(curr_char);
}
}
}
- else if (my_isdigit(system_charset_info,
- file_buff->get_value(curr_offset)))
+ else
{
- for(;curr_offset < end_offset; curr_offset++)
+ for(; curr_offset < end_offset; curr_offset++)
{
- if (file_buff->get_value(curr_offset) == ',')
+ curr_char= file_buff->get_value(curr_offset);
+ if (curr_char == ',')
{
- curr_offset+= 1; // Move past the ,
+ curr_offset++; // Skip the ,
break;
}
-
- if (my_isdigit(system_charset_info, file_buff->get_value(curr_offset)))
- buffer.append(file_buff->get_value(curr_offset));
- else if (file_buff->get_value(curr_offset) == '.')
- buffer.append(file_buff->get_value(curr_offset));
- else
- goto err;
+ buffer.append(curr_char);
}
}
- else
- {
- goto err;
- }
if (bitmap_is_set(table->read_set, (*field)->field_index))
- (*field)->store(buffer.ptr(), buffer.length(), buffer.charset());
+ {
+ if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset()))
+ goto err;
+ }
}
next_position= end_offset + eoln_len;
error= 0;
@@ -1004,6 +1002,7 @@ 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 */
@@ -1015,6 +1014,7 @@ 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,6 +1298,7 @@ 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)))
{
rows_repaired++;
@@ -1463,6 +1464,7 @@ 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)))
{
count--;