Commit c60a75e9 authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Add warnings for single line inserts. To do this I had to convert...

Add warnings for single line inserts. To do this I had to convert count_cuted_fields to an enum (to be able to detect setting a NOT NULL field to NULL)
parent a533d886
drop table if exists t1;
CREATE TABLE t1 SELECT _utf8'test' as c1, _utf8'тест' as c2;
SHOW CREATE TABLE t1;
Table Create Table
......@@ -15,6 +16,10 @@ t1 CREATE TABLE `t1` (
`c3` char(4) character set utf8 default NULL
) TYPE=MyISAM CHARSET=latin1
INSERT INTO t1 VALUES ('aaaabbbbccccdddd','aaaabbbbccccdddd','aaaabbbbccccdddd');
Warnings:
Warning 1264 Data truncated for column 'c1' at row 1
Warning 1264 Data truncated for column 'c2' at row 1
Warning 1264 Data truncated for column 'c3' at row 1
SELECT * FROM t1;
c1 c2 c3
aaaabbbbcccc aaaabbbbcccc aaaabbbbcccc
......
......@@ -75,6 +75,8 @@ NULL this is null
drop table t1;
CREATE TABLE t1 (a varchar(16) NOT NULL, b smallint(6) NOT NULL, c datetime NOT NULL, d smallint(6) NOT NULL);
INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55";
Warnings:
Warning 1264 Data truncated for column 'd' at row 1
UPDATE t1 SET d=1/NULL;
Warnings:
Warning 1264 Data truncated for column 'd' at row 1
......
......@@ -136,7 +136,7 @@ email104
email105
email106
email107
INSERT INTO `t1` (`id`, `kid`) VALUES ('', '150');
INSERT INTO `t1` (`id`, `kid`) VALUES ('0', '150');
SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
email
email1
......
......@@ -92,6 +92,8 @@ Warning 1264 Data truncated for column 'b' at row 3
Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 4
Warning 1264 Data truncated for column 'b' at row 4
insert into t2(b) values('mysqlab');
Warnings:
Warning 1264 Data truncated for column 'b' at row 1
set sql_warnings=1;
insert into t2(b) values('mysqlab');
Warnings:
......
#
# Test of alter table
#
--disable_warnings
drop table if exists t1;
--enable_warnings
CREATE TABLE t1 SELECT _utf8'test' as c1, _utf8'тест' as c2;
SHOW CREATE TABLE t1;
DELETE FROM t1;
......
......@@ -34,6 +34,7 @@ create table t1 (a tinyint not null auto_increment, b blob not null, primary key
let $1=100;
disable_query_log;
--disable_warnings
SET SQL_WARNINGS=0;
while ($1)
{
......@@ -41,6 +42,7 @@ while ($1)
dec $1;
}
SET SQL_WARNINGS=1;
--enable_warnings
enable_query_log;
check table t1;
repair table t1;
......
......@@ -64,7 +64,7 @@ SELECT FOUND_ROWS();
SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL ORDER BY email LIMIT 10;
INSERT INTO `t1` (`id`, `kid`) VALUES ('', '150');
INSERT INTO `t1` (`id`, `kid`) VALUES ('0', '150');
SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
SELECT FOUND_ROWS();
......
......@@ -119,7 +119,7 @@ set_field_to_null(Field *field)
return 0;
}
field->reset();
if (current_thd->count_cuted_fields)
if (current_thd->count_cuted_fields == CHECK_FIELD_WARN)
{
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,ER_WARN_DATA_TRUNCATED);
return 0;
......@@ -176,7 +176,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
field->table->auto_increment_field_not_null= false;
return 0; // field is set in handler.cc
}
if (current_thd->count_cuted_fields)
if (current_thd->count_cuted_fields == CHECK_FIELD_WARN)
{
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,ER_WARN_NULL_TO_NOTNULL);
return 0;
......
......@@ -2200,6 +2200,9 @@ double user_var_entry::val(my_bool *null_value)
return (double) *(longlong*) value;
case STRING_RESULT:
return atof(value); // This is null terminated
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
}
return 0.0; // Impossible
}
......@@ -2219,6 +2222,9 @@ longlong user_var_entry::val_int(my_bool *null_value)
return *(longlong*) value;
case STRING_RESULT:
return strtoull(value,NULL,10); // String is null terminated
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
}
return LL(0); // Impossible
}
......@@ -2242,6 +2248,9 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
case STRING_RESULT:
if (str->copy(value, length, collation.collation))
str= 0; // EOM error
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
}
return(str);
}
......
......@@ -90,8 +90,9 @@ THD::THD():user_time(0), is_fatal_error(0),
{
host=user=priv_user=db=query=ip=0;
host_or_ip= "connecting host";
locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password=
locked=killed=some_tables_deleted=no_errors=password=
query_start_used=prepare_command=0;
count_cuted_fields= CHECK_FIELD_IGNORE;
db_length=query_length=col_access=0;
query_error= tmp_table_used= 0;
next_insert_id=last_insert_id=0;
......
......@@ -34,6 +34,9 @@ enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN}
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 };
extern char internal_table_name[2];
/* log info errors */
......@@ -568,6 +571,7 @@ class THD :public ilink
uint select_number; //number of select (used for EXPLAIN)
/* variables.transaction_isolation is reset to this after each commit */
enum_tx_isolation session_tx_isolation;
enum_check_fields count_cuted_fields;
/* for user variables replication*/
DYNAMIC_ARRAY user_var_events;
......@@ -575,7 +579,7 @@ class THD :public ilink
char scramble[SCRAMBLE_LENGTH+1];
bool slave_thread;
bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
bool set_query_id,locked,some_tables_deleted;
bool last_cuted_field;
bool no_errors, allow_sum_func, password, is_fatal_error;
bool query_start_used,last_insert_id_used,insert_id_used,rand_used;
......
......@@ -240,9 +240,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
info.handle_duplicates=duplic;
info.update_fields=&update_fields;
info.update_values=&update_values;
// Don't count warnings for simple inserts
if (values_list.elements > 1 || (thd->options & OPTION_WARNINGS))
thd->count_cuted_fields = 1;
/*
Count warnings for all inserts.
For single line insert, generate an error if try to set a NOT NULL field
to NULL
*/
thd->count_cuted_fields= ((values_list.elements == 1) ?
CHECK_FIELD_ERROR_FOR_NULL :
CHECK_FIELD_WARN);
thd->cuted_fields = 0L;
table->next_number_field=table->found_next_number_field;
......@@ -394,7 +399,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
}
thd->proc_info="end";
table->next_number_field=0;
thd->count_cuted_fields=0;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
thd->next_insert_id=0; // Reset this if wrongly used
if (duplic != DUP_ERROR)
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
......@@ -1391,7 +1396,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
restore_record(table,default_values); // Get empty record
table->next_number_field=table->found_next_number_field;
thd->count_cuted_fields=1; // calc cuted fields
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0;
if (info.handle_duplicates != DUP_REPLACE)
table->file->extra(HA_EXTRA_WRITE_CACHE);
......@@ -1409,7 +1414,7 @@ select_insert::~select_insert()
table->next_number_field=0;
table->file->extra(HA_EXTRA_RESET);
}
thd->count_cuted_fields=0;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
}
......@@ -1559,7 +1564,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
table->next_number_field=table->found_next_number_field;
restore_record(table,default_values); // Get empty record
thd->count_cuted_fields=1; // count warnings
thd->count_cuted_fields= CHECK_FIELD_WARN; // count warnings
thd->cuted_fields=0;
if (info.handle_duplicates == DUP_IGNORE ||
info.handle_duplicates == DUP_REPLACE)
......
......@@ -252,7 +252,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
restore_record(table,default_values);
thd->count_cuted_fields=1; /* calc cuted fields */
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
thd->cuted_fields=0L;
if (ex->line_term->length() && field_term->length())
{
......@@ -293,7 +293,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (file >= 0) my_close(file,MYF(0));
free_blobs(table); /* if pack_blob was used */
table->copy_blobs=0;
thd->count_cuted_fields=0; /* Don`t calc cuted fields */
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
/*
We must invalidate the table in query cache before binlog writing and
......
......@@ -3218,9 +3218,9 @@ store_val_in_field(Field *field,Item *item)
bool error;
THD *thd=current_thd;
ha_rows cuted_fields=thd->cuted_fields;
thd->count_cuted_fields=1;
thd->count_cuted_fields= CHECK_FIELD_WARN;
error= item->save_in_field(field, 1);
thd->count_cuted_fields=0;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
return error || cuted_fields != thd->cuted_fields;
}
......
......@@ -2236,7 +2236,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (use_timestamp)
new_table->time_stamp=0;
new_table->next_number_field=new_table->found_next_number_field;
thd->count_cuted_fields=1; // calc cuted fields
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0L;
thd->proc_info="copy to tmp table";
next_insert_id=thd->next_insert_id; // Remember for loggin
......@@ -2246,7 +2246,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
handle_duplicates,
order_num, order, &copied, &deleted);
thd->last_insert_id=next_insert_id; // Needed for correct log
thd->count_cuted_fields=0; // Don`t calc cuted fields
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
new_table->time_stamp=save_time_stamp;
if (table->tmp_table)
......
......@@ -295,7 +295,7 @@ int mysql_update(THD *thd,
init_read_record(&info,thd,table,select,0,1);
updated= found= 0;
thd->count_cuted_fields=1; /* calc cuted fields */
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
thd->cuted_fields=0L;
thd->proc_info="Updating";
query_id=thd->query_id;
......@@ -386,7 +386,7 @@ int mysql_update(THD *thd,
thd->insert_id_used ? thd->insert_id() : 0L,buff);
DBUG_PRINT("info",("%d records updated",updated));
}
thd->count_cuted_fields=0; /* calc cuted fields */
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
free_io_cache(table);
DBUG_RETURN(0);
......@@ -492,7 +492,7 @@ int multi_update::prepare(List<Item> &not_used_values, SELECT_LEX_UNIT *unit)
uint i, max_fields;
DBUG_ENTER("multi_update::prepare");
thd->count_cuted_fields=1;
thd->count_cuted_fields= CHECK_FIELD_WARN;
thd->cuted_fields=0L;
thd->proc_info="updating main table";
......@@ -733,7 +733,7 @@ multi_update::~multi_update()
}
if (copy_field)
delete [] copy_field;
thd->count_cuted_fields=0; // Restore this setting
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
if (!trans_safe)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment