=== modified file 'sql/sql_delete.cc' --- sql/sql_delete.cc 2009-06-19 08:24:43 +0000 +++ sql/sql_delete.cc 2009-06-20 16:52:27 +0000 @@ -160,6 +160,7 @@ if (conds) { Item::cond_result result; + conds= ODBC_specific_QT(thd, conds, &result); conds= remove_eq_conds(thd, conds, &result); if (result == Item::COND_FALSE) // Impossible where limit= 0; === modified file 'sql/sql_select.cc' --- sql/sql_select.cc 2009-06-17 14:56:44 +0000 +++ sql/sql_select.cc 2009-06-20 16:50:46 +0000 @@ -8960,12 +8960,90 @@ Remove all and-levels where CONST item != CONST item */ DBUG_EXECUTE("where",print_where(conds,"after const change", QT_ORDINARY);); + conds= ODBC_specific_QT(thd, conds, cond_value); conds= remove_eq_conds(thd, conds, cond_value) ; DBUG_EXECUTE("info",print_where(conds,"after remove", QT_ORDINARY);); } DBUG_RETURN(conds); } +COND * +ODBC_specific_QT(THD *thd, COND *cond, Item::cond_result *cond_value) +{ + if (cond->type() == Item::FUNC_ITEM && + ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) + { + /* + Handles this special case for some ODBC applications: + The are requesting the row that was just updated with a auto_increment + value with this construct: + + SELECT * from table_name where auto_increment_column IS NULL + This will be changed to: + SELECT * from table_name where auto_increment_column = LAST_INSERT_ID + */ + + Item_func_isnull *func=(Item_func_isnull*) cond; + Item **args= func->arguments(); + if (args[0]->type() == Item::FIELD_ITEM) + { + Field *field=((Item_field*) args[0])->field; + if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null && + (thd->options & OPTION_AUTO_IS_NULL) && + (thd->first_successful_insert_id_in_prev_stmt > 0 && + thd->substitute_null_with_insert_id)) + { +#ifdef HAVE_QUERY_CACHE + query_cache_abort(&thd->net); +#endif + COND *new_cond; + if ((new_cond= new Item_func_eq(args[0], + new Item_int("last_insert_id()", + thd->read_first_successful_insert_id_in_prev_stmt(), + MY_INT64_NUM_DECIMAL_DIGITS)))) + { + cond=new_cond; + /* + Item_func_eq can't be fixed after creation so we do not check + cond->fixed, also it do not need tables so we use 0 as second + argument. + */ + cond->fix_fields(thd, &cond); + } + /* + IS NULL should be mapped to LAST_INSERT_ID only for first row, so + clear for next row + */ + thd->substitute_null_with_insert_id= FALSE; + } + /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */ + else if (((field->type() == MYSQL_TYPE_DATE) || + (field->type() == MYSQL_TYPE_DATETIME)) && + (field->flags & NOT_NULL_FLAG) && + !field->table->maybe_null) + { + COND *new_cond; + if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2)))) + { + cond=new_cond; + /* + Item_func_eq can't be fixed after creation so we do not check + cond->fixed, also it do not need tables so we use 0 as second + argument. + */ + cond->fix_fields(thd, &cond); + } + } + } + if (cond->const_item()) + { + *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE; + return (COND*) 0; + } + } + *cond_value=Item::COND_OK; + return cond; +} /** Remove const and eq items. @@ -9039,77 +9117,6 @@ return item; } } - else if (cond->type() == Item::FUNC_ITEM && - ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) - { - /* - Handles this special case for some ODBC applications: - The are requesting the row that was just updated with a auto_increment - value with this construct: - - SELECT * from table_name where auto_increment_column IS NULL - This will be changed to: - SELECT * from table_name where auto_increment_column = LAST_INSERT_ID - */ - - Item_func_isnull *func=(Item_func_isnull*) cond; - Item **args= func->arguments(); - if (args[0]->type() == Item::FIELD_ITEM) - { - Field *field=((Item_field*) args[0])->field; - if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null && - (thd->options & OPTION_AUTO_IS_NULL) && - (thd->first_successful_insert_id_in_prev_stmt > 0 && - thd->substitute_null_with_insert_id)) - { -#ifdef HAVE_QUERY_CACHE - query_cache_abort(&thd->net); -#endif - COND *new_cond; - if ((new_cond= new Item_func_eq(args[0], - new Item_int("last_insert_id()", - thd->read_first_successful_insert_id_in_prev_stmt(), - MY_INT64_NUM_DECIMAL_DIGITS)))) - { - cond=new_cond; - /* - Item_func_eq can't be fixed after creation so we do not check - cond->fixed, also it do not need tables so we use 0 as second - argument. - */ - cond->fix_fields(thd, &cond); - } - /* - IS NULL should be mapped to LAST_INSERT_ID only for first row, so - clear for next row - */ - thd->substitute_null_with_insert_id= FALSE; - } - /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */ - else if (((field->type() == MYSQL_TYPE_DATE) || - (field->type() == MYSQL_TYPE_DATETIME)) && - (field->flags & NOT_NULL_FLAG) && - !field->table->maybe_null) - { - COND *new_cond; - if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2)))) - { - cond=new_cond; - /* - Item_func_eq can't be fixed after creation so we do not check - cond->fixed, also it do not need tables so we use 0 as second - argument. - */ - cond->fix_fields(thd, &cond); - } - } - } - if (cond->const_item()) - { - *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE; - return (COND*) 0; - } - } else if (cond->const_item()) { *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE; === modified file 'sql/sql_select.h' --- sql/sql_select.h 2009-02-23 16:16:48 +0000 +++ sql/sql_select.h 2009-06-20 18:31:13 +0000 @@ -728,6 +728,7 @@ bool error_if_full_join(JOIN *join); int report_error(TABLE *table, int error); int safe_index_read(JOIN_TAB *tab); +COND *ODBC_specific_QT(THD *thd, COND *cond, Item::cond_result *cond_value); COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value); inline bool optimizer_flag(THD *thd, uint flag) === modified file 'sql/sql_update.cc' --- sql/sql_update.cc 2009-06-18 14:16:14 +0000 +++ sql/sql_update.cc 2009-06-20 16:52:00 +0000 @@ -297,6 +297,7 @@ if (conds) { Item::cond_result cond_value; + conds= ODBC_specific_QT(thd, conds, &cond_value); conds= remove_eq_conds(thd, conds, &cond_value); if (cond_value == Item::COND_FALSE) limit= 0; // Impossible WHERE