4222 Dmitry Shulga 2012-10-02
Follow-up patch for WL#6030.
The test related to warnings count was changed in mysql_client_test.c
Field::set_waring takes into account commands v and REPLACE_SELECT.
During execution INSERT SELECT set thd->count_cuted_fields
temporary to value CHECK_FIELD_WARN in order to outpyt warnings related
to missed values for fields that doesn't have defautl values.
modified:
sql/field.cc
sql/sql_insert.cc
tests/mysql_client_test.c
4221 Dmitry Shulga 2012-10-02
Fixed failures in the tests INSERT SELECT and LOAD DATA INFILE
related with NOT NULL columns.
modified:
mysql-test/r/wl6030.result
sql/sql_insert.cc
sql/sql_load.cc
4220 Dmitry Shulga 2012-10-01
Missed_fields_handler was removed.
modified:
sql/field.cc
sql/field.h
sql/sql_insert.cc
sql/sql_insert.h
sql/sql_load.cc
sql/sql_trigger.cc
4219 Alexander Nozdrin 2012-09-28
Fixing wl6030.test/wl6030.result (the test does not pass now).
modified:
mysql-test/r/wl6030.result
mysql-test/t/wl6030.test
=== modified file 'mysql-test/r/wl6030.result'
--- a/mysql-test/r/wl6030.result 2012-09-28 07:55:02 +0000
+++ b/mysql-test/r/wl6030.result 2012-10-02 05:35:46 +0000
@@ -1116,9 +1116,9 @@ DELETE FROM t2;
# - No column list (all columns) + NULL-value for NOT NULL column.
INSERT INTO t2 SELECT * FROM t2_data;
-ERROR 23000: Column 'd' cannot be null
+ERROR 23000: Column 'b' cannot be null
INSERT INTO v2 SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
-ERROR 23000: Column 'd' cannot be null
+ERROR 23000: Column 'b' cannot be null
# The following SELECT output should have 4 rows.
# t2's engine is MyISAM, so the transaction can not be fully rolled back.
@@ -1152,9 +1152,9 @@ DELETE FROM t1;
DELETE FROM t2;
INSERT INTO t2(a, b, c, d) SELECT * FROM t2_data;
-ERROR 23000: Column 'd' cannot be null
+ERROR 23000: Column 'b' cannot be null
INSERT INTO v2(a, b, c, d) SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
-ERROR 23000: Column 'd' cannot be null
+ERROR 23000: Column 'b' cannot be null
# The following SELECT output should have 4 rows.
# t2's engine is MyISAM, so the transaction can not be fully rolled back.
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2012-09-27 14:40:40 +0000
+++ b/sql/field.cc 2012-10-02 09:31:52 +0000
@@ -1360,7 +1360,7 @@ Field::Field(uchar *ptr_arg,uint32 lengt
unireg_check(unireg_check_arg),
field_length(length_arg), null_bit(null_bit_arg),
is_created_from_null_item(FALSE),
- field_warning_was_pushed(false)
+ field_warning_was_pushed(0)
{
flags=real_maybe_null() ? 0: NOT_NULL_FLAG;
comment.str= (char*) "";
@@ -10578,6 +10578,15 @@ bool
Field::set_warning(Sql_condition::enum_warning_level level, uint code,
int cut_increment)
{
+ return set_warning(level, code, cut_increment, NULL, NULL);
+}
+
+
+bool
+Field::set_warning(Sql_condition::enum_warning_level level, uint code,
+ int cut_increment, const char *view_db,
+ const char *view_name)
+{
/*
If this field was created only for type conversion purposes it
will have table == NULL.
@@ -10587,16 +10596,39 @@ Field::set_warning(Sql_condition::enum_w
{
thd->cuted_fields+= cut_increment;
if ((thd->lex->sql_command == SQLCOM_INSERT ||
- thd->lex->sql_command == SQLCOM_INSERT_SELECT) &&
- (code == ER_BAD_NULL_ERROR ||
- code == ER_WARN_NULL_TO_NOTNULL))
- {
- if (!field_warning_was_pushed)
+ thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
+ thd->lex->sql_command == SQLCOM_REPLACE) ||
+ thd->lex->sql_command == SQLCOM_REPLACE_SELECT)
+ {
+ unsigned bitmask;
+ if ((code == ER_BAD_NULL_ERROR && (bitmask= BAD_NULL_ERROR_PUSHED)) ||
+ (code == ER_WARN_NULL_TO_NOTNULL &&
+ (bitmask= WARN_NULL_TO_NOTNULL_PUSHED)) ||
+ (code == ER_NO_DEFAULT_FOR_FIELD &&
+ (bitmask= NO_DEFAULT_FOR_FIELD_PUSHED)))
+ {
+ if (!(field_warning_was_pushed & bitmask))
+ {
+ push_warning_printf(thd, level, code, ER(code), field_name,
+ thd->get_stmt_da()->current_row_for_warning());
+ field_warning_was_pushed|= bitmask;
+ }
+ }
+ else if (code == ER_NO_DEFAULT_FOR_VIEW_FIELD)
{
- field_warning_was_pushed= true;
+ if (!(field_warning_was_pushed & NO_DEFAULT_FOR_VIEW_FIELD_PUSHED))
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_NO_DEFAULT_FOR_VIEW_FIELD,
+ ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
+ view_db,
+ view_name);
+ field_warning_was_pushed|= NO_DEFAULT_FOR_VIEW_FIELD_PUSHED;
+ }
+ }
+ else
push_warning_printf(thd, level, code, ER(code), field_name,
thd->get_stmt_da()->current_row_for_warning());
- }
}
else
push_warning_printf(thd, level, code, ER(code), field_name,
=== modified file 'sql/field.h'
--- a/sql/field.h 2012-09-27 14:40:40 +0000
+++ b/sql/field.h 2012-10-01 03:34:26 +0000
@@ -568,12 +568,16 @@ public:
bool is_created_from_null_item;
private:
- bool field_warning_was_pushed;
+ unsigned field_warning_was_pushed;
+ enum pushed_warns_mask_e {BAD_NULL_ERROR_PUSHED= 1,
+ WARN_NULL_TO_NOTNULL_PUSHED= 2,
+ NO_DEFAULT_FOR_FIELD_PUSHED= 4,
+ NO_DEFAULT_FOR_VIEW_FIELD_PUSHED= 8};
public:
void reset_warning_flag()
{
- field_warning_was_pushed= false;
+ field_warning_was_pushed= 0;
}
Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
@@ -1250,6 +1254,10 @@ public:
virtual void set_derivation(enum Derivation derivation_arg) { }
bool set_warning(Sql_condition::enum_warning_level, unsigned int code,
int cuted_increment);
+ bool set_warning(Sql_condition::enum_warning_level level, uint code,
+ int cut_increment, const char *view_db,
+ const char *view_name);
+
inline bool check_overflow(int op_result)
{
return (op_result == E_DEC_OVERFLOW);
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2012-09-27 14:40:40 +0000
+++ b/sql/sql_insert.cc 2012-10-02 09:31:52 +0000
@@ -609,79 +609,6 @@ create_insert_stmt_from_insert_delayed(T
}
-void Missed_fields_handler_impl::handle(bool is_view, Field* field,
- TABLE_LIST* table_list)
-{
- if (is_view)
- add_field_idx_to_missed_set(field->field_index,
- const_cast<char*>(field->field_name),
- table_list->view_db.str,
- table_list->view_name.str);
- else
- add_field_idx_to_missed_set(field->field_index,
- const_cast<char*>(field->field_name));
-}
-
-
-void Missed_fields_handler_impl::process_missed_fields()
-{
- List_iterator_fast<char> its(missed_fields_name_list);
- const char *field_name= NULL;
-
- bool saved_abort_on_warning= thd->abort_on_warning;
- thd->abort_on_warning= !ignore_errors &&
- thd->is_strict_mode();
-
- for(unsigned i=0; i<number_of_missed_fields; i++)
- {
- field_name= its++;
- if (is_view)
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_NO_DEFAULT_FOR_VIEW_FIELD,
- ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
- view_db,
- view_name);
- }
- else
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_NO_DEFAULT_FOR_FIELD,
- ER(ER_NO_DEFAULT_FOR_FIELD),
- field_name);
- }
- }
- thd->abort_on_warning= saved_abort_on_warning;
-}
-
-
-void Missed_fields_handler_impl::add_field_idx_to_missed_set(uint16 field_idx,
- char* field_name)
-{
- if (!bitmap_is_set(&fields_not_set_during_insert, field_idx))
- {
- bitmap_set_bit(&fields_not_set_during_insert, field_idx);
- ++number_of_missed_fields;
- missed_fields_name_list.push_back(field_name);
- }
-}
-
-
-void Missed_fields_handler_impl::add_field_idx_to_missed_set(uint16 field_idx,
- char* field_name,
- const char* v_db,
- const char* v_nam)
-{
- add_field_idx_to_missed_set(field_idx, field_name);
- if (!is_view)
- {
- view_db= v_db;
- view_name= v_nam;
- is_view= true;
- }
-}
-
-
/**
Wrapper for invocation of function check_that_all_fields_are_given_value.
@@ -698,14 +625,12 @@ void Missed_fields_handler_impl::add_fie
static bool
safely_check_that_all_fields_are_given_values(THD* thd, TABLE* table,
TABLE_LIST* table_list,
- bool abort_on_warning,
- Missed_fields_handler *handler)
+ bool abort_on_warning)
{
bool saved_abort_on_warning= thd->abort_on_warning;
thd->abort_on_warning= abort_on_warning;
- bool res= check_that_all_fields_are_given_values(thd, table, table_list,
- handler);
+ bool res= check_that_all_fields_are_given_values(thd, table, table_list);
thd->abort_on_warning= saved_abort_on_warning;
@@ -863,10 +788,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
DBUG_RETURN(true);
}
- Missed_fields_handler_impl miss_flds_handler(thd, ignore,
- table->s->column_bitmap_size,
- table->s->fields);
-
context= &thd->lex->select_lex.context;
/*
These three asserts test the hypothesis that the resetting of the name
@@ -1091,6 +1012,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
table_list->prepare_check_option(thd))
error= 1;
+ for (Field** next_field= table->field; *next_field; ++next_field)
+ {
+ (*next_field)->reset_warning_flag();
+ }
+
while ((values= its++))
{
if (fields.elements || !value_count)
@@ -1121,8 +1047,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
bool abort_on_warning= !ignore && thd->is_strict_mode();
res= safely_check_that_all_fields_are_given_values(thd, t,
context->table_list,
- abort_on_warning,
- &miss_flds_handler);
+ abort_on_warning);
if (res)
{
@@ -1202,9 +1127,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
thd->get_stmt_da()->inc_current_row_for_warning();
}
- if (miss_flds_handler.have_missed_fields())
- miss_flds_handler.process_missed_fields();
-
error= thd->get_stmt_da()->is_error();
free_underlaid_joins(thd, &thd->lex->select_lex);
joins_freed= TRUE;
@@ -2049,8 +1971,7 @@ before_trg_err:
******************************************************************************/
int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
- TABLE_LIST *table_list,
- Missed_fields_handler *handler)
+ TABLE_LIST *table_list)
{
int err= 0;
MY_BITMAP *write_set= entry->fields_set_during_insert;
@@ -2067,7 +1988,14 @@ int check_that_all_fields_are_given_valu
table_list= table_list->top_table();
view= test(table_list->view);
}
- handler->handle(view, *field, table_list);
+ if (view)
+ (*field)->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ ER_NO_DEFAULT_FOR_VIEW_FIELD, 1,
+ table_list->view_db.str,
+ table_list->view_name.str);
+ else
+ (*field)->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ ER_NO_DEFAULT_FOR_FIELD, 1);
err= 1;
}
}
@@ -3667,6 +3595,13 @@ select_insert::prepare(List<Item> &value
{
prepare_triggers_for_insert_stmt(table);
}
+
+ for (Field** next_field= table->field; *next_field; ++next_field)
+ {
+ (*next_field)->reset_warning_flag();
+ (*next_field)->reset_tmp_null();
+ }
+
DBUG_RETURN(res);
}
@@ -3801,14 +3736,7 @@ void select_insert::store_values(List<It
table->triggers, TRG_EVENT_INSERT,
table->s->fields);
- check_that_all_fields_are_given_values(thd, table_list->table, table_list,
- &missed_fields_handler);
-
- if (!info.get_ignore_errors() && thd->is_strict_mode() &&
- missed_fields_handler.have_missed_fields())
- {
- missed_fields_handler.process_missed_fields();
- }
+ check_that_all_fields_are_given_values(thd, table_list->table, table_list);
}
void select_insert::send_error(uint errcode,const char *err)
@@ -3883,11 +3811,6 @@ bool select_insert::send_eof()
DBUG_RETURN(1);
}
- if (missed_fields_handler.have_missed_fields())
- {
- missed_fields_handler.process_missed_fields();
- }
-
/*
For the strict_mode call of push_warning above results to set
error in Diagnostic_area. Therefore it is necessary to check whether
@@ -4334,16 +4257,14 @@ select_create::prepare2()
if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
table->file->ha_start_bulk_insert((ha_rows) 0);
thd->abort_on_warning= (!ignore_errors && thd->is_strict_mode());
- Missed_fields_handler_impl miss_flds_handler(thd, ignore_errors,
- table->s->column_bitmap_size,
- table->s->fields);
- if (check_that_all_fields_are_given_values(thd, table, table_list,
- &miss_flds_handler))
+ enum_check_fields save_coiunt_cuted_fields= thd->count_cuted_fields;
+ thd->count_cuted_fields= CHECK_FIELD_WARN;
+
+ if (check_that_all_fields_are_given_values(thd, table, table_list))
DBUG_RETURN(1);
- if (miss_flds_handler.have_missed_fields())
- miss_flds_handler.process_missed_fields();
+ thd->count_cuted_fields= save_coiunt_cuted_fields;
table->mark_columns_needed_for_insert();
table->file->extra(HA_EXTRA_WRITE_CACHE);
=== modified file 'sql/sql_insert.h'
--- a/sql/sql_insert.h 2012-09-27 14:40:40 +0000
+++ b/sql/sql_insert.h 2012-10-01 03:34:26 +0000
@@ -37,75 +37,6 @@ void upgrade_lock_type_for_insert(THD *t
bool is_multi_insert);
-/**
- Interface for handling table fields that isn't specified in INSERT statement
- and doesn't have DEFAULT value in table definition.
-
- This interface is called for INSERT and INSERT SELECT
- statements.
-*/
-class Missed_fields_handler
-{
-public:
- virtual ~Missed_fields_handler() {}
-
- virtual void handle(bool is_view, Field* field, TABLE_LIST* table_list) = 0;
-};
-
-
-/**
- This class implements interface Missed_fields_handler.
-*/
-class Missed_fields_handler_impl : public Missed_fields_handler
-{
-public:
- Missed_fields_handler_impl(THD* thd_val, bool ignore_errs,
- uint column_bitmap_size, uint number_of_fields)
- : thd(thd_val), number_of_missed_fields(0),
- is_view(false), ignore_errors(ignore_errs)
- {
- if (column_bitmap_size)
- {
- uchar* bitmaps= (uchar*) alloc_root(thd->mem_root,
- column_bitmap_size);
- if (bitmaps)
- {
- bitmap_init(&fields_not_set_during_insert,
- (my_bitmap_map*) (bitmaps),
- number_of_fields,
- false);
- }
- }
- }
-
- virtual void handle(bool is_view, Field* field, TABLE_LIST* table_list);
-
- bool have_missed_fields() const
- {
- return number_of_missed_fields != 0;
- }
-
- void process_missed_fields();
-
-private:
- void add_field_idx_to_missed_set(uint16 field_index, char* field_name);
-
- void add_field_idx_to_missed_set(uint16 field_index, char* field_name,
- const char* v_db, const char* v_name);
-
- THD* thd;
-
- unsigned number_of_missed_fields;
- bool is_view, ignore_errors;
-
- MY_BITMAP fields_not_set_during_insert;
- List<char> missed_fields_name_list;
-
- const char* view_db;
- const char* view_name;
-};
-
-
class select_insert :public select_result_interceptor {
public:
TABLE_LIST *table_list;
@@ -118,8 +49,6 @@ private:
*/
List<Item> *fields;
- Missed_fields_handler_impl missed_fields_handler;
-
public:
ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not
COPY_INFO info;
@@ -187,9 +116,6 @@ public:
:table_list(table_list_par),
table(table_par),
fields(target_or_source_columns),
- missed_fields_handler(thd, ignore,
- (table ? table->s->column_bitmap_size : 0),
- (table ? table->s->fields : 0)),
autoinc_value_of_last_inserted_row(0),
info(COPY_INFO::INSERT_OPERATION,
target_columns,
@@ -274,8 +200,7 @@ public:
int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
- TABLE_LIST *table_list,
- Missed_fields_handler *handler);
+ TABLE_LIST *table_list);
void prepare_triggers_for_insert_stmt(TABLE *table);
int write_record(THD *thd, TABLE *table,
COPY_INFO *info, COPY_INFO *update);
=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc 2012-09-27 14:40:40 +0000
+++ b/sql/sql_load.cc 2012-10-02 05:35:46 +0000
@@ -292,17 +292,12 @@ int mysql_load(THD *thd,sql_exchange *ex
}
else
{ // Part field list
- Missed_fields_handler_impl miss_flds_handler(thd, ignore,
- table->s->column_bitmap_size,
- table->s->fields);
-
/* TODO: use this conds for 'WITH CHECK OPTIONS' */
if (setup_fields(thd, Ref_ptr_array(),
fields_vars, MARK_COLUMNS_WRITE, 0, 0) ||
setup_fields(thd, Ref_ptr_array(),
set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
- check_that_all_fields_are_given_values(thd, table, table_list,
- &miss_flds_handler))
+ check_that_all_fields_are_given_values(thd, table, table_list))
DBUG_RETURN(TRUE);
/* Fix the expressions in SET clause */
if (setup_fields(thd, Ref_ptr_array(), set_values, MARK_COLUMNS_READ, 0, 0))
@@ -1144,6 +1139,9 @@ read_sep_field(THD *thd, COPY_INFO &info
}
}
+ if (thd->is_error())
+ DBUG_RETURN(1);
+
switch (table_list->view_check_option(thd,
ignore_check_option_errors)) {
case VIEW_CHECK_SKIP:
=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc 2012-09-27 14:40:40 +0000
+++ b/sql/sql_trigger.cc 2012-10-01 03:34:26 +0000
@@ -2255,7 +2255,6 @@ void Table_triggers_list::enable_fields_
if (thd->lex->sql_command != SQLCOM_LOAD)
{
(*next_field)->reset_tmp_null();
- (*next_field)->reset_warning_flag();
}
(*next_field)->set_count_cuted_fields(thd->count_cuted_fields);
}
=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c 2012-07-26 18:46:34 +0000
+++ b/tests/mysql_client_test.c 2012-10-02 09:31:52 +0000
@@ -7847,7 +7847,7 @@ static void test_cuted_rows()
count= mysql_warning_count(mysql);
if (!opt_silent)
fprintf(stdout, "\n total warnings: %d", count);
- DIE_UNLESS(count == 2);
+ DIE_UNLESS(count == 1);
rc= mysql_query(mysql, "SHOW WARNINGS");
myquery(rc);
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (Dmitry.Shulga:4219 to 4222) WL#6030 | Dmitry Shulga | 2 Oct |