diff options
-rw-r--r-- | mysql-test/include/ctype_numconv.inc | 2 | ||||
-rw-r--r-- | mysql-test/r/ctype_binary.result | 3 | ||||
-rw-r--r-- | mysql-test/r/ctype_cp1251.result | 3 | ||||
-rw-r--r-- | mysql-test/r/ctype_latin1.result | 3 | ||||
-rw-r--r-- | mysql-test/r/ctype_ucs.result | 3 | ||||
-rw-r--r-- | mysql-test/r/sp.result | 4 | ||||
-rw-r--r-- | mysql-test/suite/funcs_1/r/innodb_storedproc_10.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/funcs_1/r/memory_storedproc_10.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/funcs_1/r/myisam_storedproc_10.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/funcs_1/r/ndb_storedproc_10.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/funcs_1/r/row_count_func.result | 79 | ||||
-rw-r--r-- | mysql-test/suite/funcs_1/t/row_count_func-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/suite/funcs_1/t/row_count_func.test | 115 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/protocol.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 15 | ||||
-rw-r--r-- | sql/sql_class.h | 49 | ||||
-rw-r--r-- | sql/sql_delete.cc | 13 | ||||
-rw-r--r-- | sql/sql_insert.cc | 22 | ||||
-rw-r--r-- | sql/sql_parse.cc | 53 | ||||
-rw-r--r-- | sql/sql_signal.cc | 14 | ||||
-rw-r--r-- | sql/sql_update.cc | 10 |
22 files changed, 321 insertions, 80 deletions
diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc index 959ca7dfeea..be82f67b9f8 100644 --- a/mysql-test/include/ctype_numconv.inc +++ b/mysql-test/include/ctype_numconv.inc @@ -457,6 +457,8 @@ select * from t1; show create table t1; drop table t1; +# Ensure that row_count() value is reset after drop table. +select 1; select hex(concat(row_count())); create table t1 as select concat(row_count()) as c1; show create table t1; diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result index 55faa72c6ab..3ffb087c1d3 100644 --- a/mysql-test/r/ctype_binary.result +++ b/mysql-test/r/ctype_binary.result @@ -772,6 +772,9 @@ t1 CREATE TABLE `t1` ( `c1` varbinary(31) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +select 1; +1 +1 select hex(concat(row_count())); hex(concat(row_count())) 2D31 diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result index cb932c38a27..e0339ee2109 100644 --- a/mysql-test/r/ctype_cp1251.result +++ b/mysql-test/r/ctype_cp1251.result @@ -854,6 +854,9 @@ t1 CREATE TABLE `t1` ( `c1` varchar(31) CHARACTER SET cp1251 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +select 1; +1 +1 select hex(concat(row_count())); hex(concat(row_count())) 2D31 diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index 4944db677a6..4f0e863bfca 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -1182,6 +1182,9 @@ t1 CREATE TABLE `t1` ( `c1` varchar(31) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +select 1; +1 +1 select hex(concat(row_count())); hex(concat(row_count())) 2D31 diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 533dfa4db34..324848be835 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -2006,6 +2006,9 @@ t1 CREATE TABLE `t1` ( `c1` varchar(31) CHARACTER SET ucs2 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +select 1; +1 +1 select hex(concat(row_count())); hex(concat(row_count())) 002D0031 diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 7d24e6db920..76d4bf2dea0 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -2590,11 +2590,11 @@ row_count() call bug4905()| select row_count()| row_count() --1 +0 call bug4905()| select row_count()| row_count() --1 +0 select * from t3| s1 1 diff --git a/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result b/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result index 24ebd38e403..a084630a305 100644 --- a/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result +++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result @@ -375,7 +375,7 @@ row_count() after delete 2 SELECT row_count(); row_count() --1 +0 SELECT * FROM temp; f1 f2 f3 f4 f5 f6 qwe xyz 1998-03-26 100 uvw 1000 diff --git a/mysql-test/suite/funcs_1/r/memory_storedproc_10.result b/mysql-test/suite/funcs_1/r/memory_storedproc_10.result index f5e34b0063c..b03f7445fb4 100644 --- a/mysql-test/suite/funcs_1/r/memory_storedproc_10.result +++ b/mysql-test/suite/funcs_1/r/memory_storedproc_10.result @@ -376,7 +376,7 @@ row_count() after delete 2 SELECT row_count(); row_count() --1 +0 SELECT * FROM temp; f1 f2 f3 f4 f5 f6 qwe xyz 1998-03-26 100 uvw 1000 diff --git a/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result b/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result index f5e34b0063c..b03f7445fb4 100644 --- a/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result +++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result @@ -376,7 +376,7 @@ row_count() after delete 2 SELECT row_count(); row_count() --1 +0 SELECT * FROM temp; f1 f2 f3 f4 f5 f6 qwe xyz 1998-03-26 100 uvw 1000 diff --git a/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result b/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result index 24ebd38e403..a084630a305 100644 --- a/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result +++ b/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result @@ -375,7 +375,7 @@ row_count() after delete 2 SELECT row_count(); row_count() --1 +0 SELECT * FROM temp; f1 f2 f3 f4 f5 f6 qwe xyz 1998-03-26 100 uvw 1000 diff --git a/mysql-test/suite/funcs_1/r/row_count_func.result b/mysql-test/suite/funcs_1/r/row_count_func.result new file mode 100644 index 00000000000..ffc0e8e3b77 --- /dev/null +++ b/mysql-test/suite/funcs_1/r/row_count_func.result @@ -0,0 +1,79 @@ + +# -- +# -- Test case for Bug#21818. +# -- + +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1), (2), (3); + +# -- Check 1. +SELECT * FROM t1 INTO OUTFILE "MYSQL_TMP_DIR/bug21818.txt"; +affected rows: 3 + +SELECT ROW_COUNT(); +ROW_COUNT() +3 + +# -- Check 2. +SELECT a FROM t1 LIMIT 1 INTO @a; +affected rows: 1 + +SELECT ROW_COUNT(); +ROW_COUNT() +1 + +# -- Check 3. +DROP DATABASE IF EXISTS mysqltest1; +CREATE DATABASE mysqltest1; +affected rows: 1 + +SELECT ROW_COUNT(); +ROW_COUNT() +1 +DROP DATABASE mysqltest1; + +# -- Check 4. +DELETE FROM t1; +LOAD DATA INFILE 'MYSQL_TMP_DIR/bug21818.txt' INTO TABLE t1(a); +affected rows: 3 +info: Records: 3 Deleted: 0 Skipped: 0 Warnings: 0 + +SELECT ROW_COUNT(); +ROW_COUNT() +3 + +# -- Check 5. +ALTER TABLE t1 ADD COLUMN b VARCHAR(255); +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 + +SELECT ROW_COUNT(); +ROW_COUNT() +3 + +DROP TABLE t1; + +# -- Check 6. +DROP TABLE IF EXISTS t2; +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +INSERT INTO t1 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (ROW_COUNT()); +SELECT * FROM t2; +a +3 +DROP TABLE t1; +DROP TABLE t2; + +# -- Check 7 (check that SQL errors reset row_count to -1). +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1), (2), (3); +SELECT f1(); +ERROR 42000: FUNCTION test.f1 does not exist +SELECT ROW_COUNT(); +ROW_COUNT() +-1 +DROP TABLE t1; + +# -- End of test case for Bug#21818. diff --git a/mysql-test/suite/funcs_1/t/row_count_func-master.opt b/mysql-test/suite/funcs_1/t/row_count_func-master.opt new file mode 100644 index 00000000000..c189eede9e4 --- /dev/null +++ b/mysql-test/suite/funcs_1/t/row_count_func-master.opt @@ -0,0 +1 @@ +--secure-file-priv=$MYSQL_TMP_DIR diff --git a/mysql-test/suite/funcs_1/t/row_count_func.test b/mysql-test/suite/funcs_1/t/row_count_func.test new file mode 100644 index 00000000000..1694928b26c --- /dev/null +++ b/mysql-test/suite/funcs_1/t/row_count_func.test @@ -0,0 +1,115 @@ +--echo +--echo # -- +--echo # -- Test case for Bug#21818. +--echo # -- +--echo + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1), (2), (3); + +--echo +--echo # -- Check 1. + +--enable_info +--echo SELECT * FROM t1 INTO OUTFILE "MYSQL_TMP_DIR/bug21818.txt"; +--disable_query_log # to avoid $MYSQL_TMP_DIR in query log +--eval SELECT * FROM t1 INTO OUTFILE "$MYSQL_TMP_DIR/bug21818.txt" +--enable_query_log +--disable_info + +--echo +SELECT ROW_COUNT(); + +--echo +--echo # -- Check 2. + +--enable_info +SELECT a FROM t1 LIMIT 1 INTO @a; +--disable_info + +--echo +SELECT ROW_COUNT(); + +--echo +--echo # -- Check 3. + +--disable_warnings +DROP DATABASE IF EXISTS mysqltest1; +--enable_warnings + +--enable_info +CREATE DATABASE mysqltest1; +--disable_info + +--echo +SELECT ROW_COUNT(); + +DROP DATABASE mysqltest1; + +--echo +--echo # -- Check 4. + +DELETE FROM t1; + +--enable_info +--echo LOAD DATA INFILE 'MYSQL_TMP_DIR/bug21818.txt' INTO TABLE t1(a); +--disable_query_log # to avoid $MYSQL_TMP_DIR in query log +--eval LOAD DATA INFILE '$MYSQL_TMP_DIR/bug21818.txt' INTO TABLE t1(a) +--enable_query_log +--disable_info + +--echo +SELECT ROW_COUNT(); + +--remove_file $MYSQL_TMP_DIR/bug21818.txt + +--echo +--echo # -- Check 5. + +--enable_info +ALTER TABLE t1 ADD COLUMN b VARCHAR(255); +--disable_info + +--echo +SELECT ROW_COUNT(); + +--echo +DROP TABLE t1; + +--echo +--echo # -- Check 6. + +--disable_warnings +DROP TABLE IF EXISTS t2; +--enable_warnings + +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); + +INSERT INTO t1 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (ROW_COUNT()); + +SELECT * FROM t2; + +DROP TABLE t1; +DROP TABLE t2; + +--echo +--echo # -- Check 7 (check that SQL errors reset row_count to -1). + +CREATE TABLE t1(a INT); + +INSERT INTO t1 VALUES (1), (2), (3); +--error ER_SP_DOES_NOT_EXIST +SELECT f1(); + +SELECT ROW_COUNT(); + +DROP TABLE t1; + +--echo +--echo # -- End of test case for Bug#21818. diff --git a/sql/item_func.cc b/sql/item_func.cc index 4d0dec25e64..26c802b8057 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6030,7 +6030,7 @@ longlong Item_func_row_count::val_int() DBUG_ASSERT(fixed == 1); THD *thd= current_thd; - return thd->row_count_func; + return thd->get_row_count_func(); } diff --git a/sql/protocol.cc b/sql/protocol.cc index e036f255960..fd01e4a8885 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -210,7 +210,7 @@ net_send_ok(THD *thd, NET *net= &thd->net; uchar buff[MYSQL_ERRMSG_SIZE+10],*pos; bool error= FALSE; - DBUG_ENTER("my_ok"); + DBUG_ENTER("net_send_ok"); if (! net->vio) // hack for re-parsing queries { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2cd9a34fba1..9ed6bdcf098 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -512,7 +512,7 @@ THD::THD() cuted_fields= 0L; sent_row_count= 0L; limit_found_rows= 0; - row_count_func= -1; + m_row_count_func= -1; statement_id_counter= 0UL; // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; @@ -804,7 +804,10 @@ MYSQL_ERROR* THD::raise_condition(uint sql_errno, else { if (! stmt_da->is_error()) + { + set_row_count_func(-1); stmt_da->set_error_status(this, sql_errno, msg, sqlstate); + } } } @@ -1805,11 +1808,6 @@ bool select_to_file::send_eof() error= 1; if (!error) { - /* - In order to remember the value of affected rows for ROW_COUNT() - function, SELECT INTO has to have an own SQLCOM. - TODO: split from SQLCOM_SELECT - */ ::my_ok(thd,row_count); } file= -1; @@ -2830,11 +2828,6 @@ bool select_dumpvar::send_eof() if (! row_count) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA)); - /* - In order to remember the value of affected rows for ROW_COUNT() - function, SELECT INTO has to have an own SQLCOM. - TODO: split from SQLCOM_SELECT - */ ::my_ok(thd,row_count); return 0; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 0a098fc8492..d9bf6c9bb98 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1994,7 +1994,50 @@ public: } ulonglong limit_found_rows; - longlong row_count_func; /* For the ROW_COUNT() function */ + +private: + /** + Stores the result of ROW_COUNT() function. + + ROW_COUNT() function is a MySQL extention, but we try to keep it + similar to ROW_COUNT member of the GET DIAGNOSTICS stack of the SQL + standard (see SQL99, part 2, search for ROW_COUNT). It's value is + implementation defined for anything except INSERT, DELETE, UPDATE. + + ROW_COUNT is assigned according to the following rules: + + - In my_ok(): + - for DML statements: to the number of affected rows; + - for DDL statements: to 0. + + - In my_eof(): to -1 to indicate that there was a result set. + + We derive this semantics from the JDBC specification, where int + java.sql.Statement.getUpdateCount() is defined to (sic) "return the + current result as an update count; if the result is a ResultSet + object or there are no more results, -1 is returned". + + - In my_error(): to -1 to be compatible with the MySQL C API and + MySQL ODBC driver. + + - For SIGNAL statements: to 0 per WL#2110 specification (see also + sql_signal.cc comment). Zero is used since that's the "default" + value of ROW_COUNT in the diagnostics area. + */ + + longlong m_row_count_func; /* For the ROW_COUNT() function */ + +public: + inline longlong get_row_count_func() const + { + return m_row_count_func; + } + + inline void set_row_count_func(longlong row_count_func) + { + m_row_count_func= row_count_func; + } + ha_rows cuted_fields; /* @@ -2781,6 +2824,7 @@ inline void my_ok(THD *thd, ulonglong affected_rows= 0, ulonglong id= 0, const char *message= NULL) { + thd->set_row_count_func(affected_rows); thd->stmt_da->set_ok_status(thd, affected_rows, id, message); } @@ -2790,6 +2834,7 @@ my_ok(THD *thd, ulonglong affected_rows= 0, ulonglong id= 0, inline void my_eof(THD *thd) { + thd->set_row_count_func(-1); thd->stmt_da->set_eof_status(thd); } @@ -3451,7 +3496,7 @@ public: /* Bits in sql_command_flags */ #define CF_CHANGES_DATA (1U << 0) -#define CF_HAS_ROW_COUNT (1U << 1) +/* The 2nd bit is unused -- it used to be CF_HAS_ROW_COUNT. */ #define CF_STATUS_COMMAND (1U << 2) #define CF_SHOW_TABLE_COMMAND (1U << 3) #define CF_WRITE_LOGS_COMMAND (1U << 4) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 2a8503077aa..10bdb8a22a6 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -187,8 +187,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (prune_partitions(thd, table, conds)) { free_underlaid_joins(thd, select_lex); - thd->row_count_func= 0; - my_ok(thd, (ha_rows) thd->row_count_func); // No matching records + // No matching record + my_ok(thd, 0); DBUG_RETURN(0); } #endif @@ -204,7 +204,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { delete select; free_underlaid_joins(thd, select_lex); - thd->row_count_func= 0; /* Error was already created by quick select evaluation (check_quick()). TODO: Add error code output parameter to Item::val_xxx() methods. @@ -213,7 +212,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, */ if (thd->is_error()) DBUG_RETURN(TRUE); - my_ok(thd, (ha_rows) thd->row_count_func); + my_ok(thd, 0); /* We don't need to call reset_auto_increment in this case, because mysql_truncate always gives a NULL conds argument, hence we never @@ -460,8 +459,7 @@ cleanup: If a TRUNCATE TABLE was issued, the number of rows should be reported as zero since the exact number is unknown. */ - thd->row_count_func= reset_auto_increment ? 0 : deleted; - my_ok(thd, (ha_rows) thd->row_count_func); + my_ok(thd, reset_auto_increment ? 0 : deleted); DBUG_PRINT("info",("%ld records deleted",(long) deleted)); } DBUG_RETURN(error >= 0 || thd->is_error()); @@ -1058,8 +1056,7 @@ bool multi_delete::send_eof() if (!local_error) { - thd->row_count_func= deleted; - ::my_ok(thd, (ha_rows) thd->row_count_func); + ::my_ok(thd, deleted); } return 0; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 103be4c851f..1f9d69a798e 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1005,10 +1005,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (values_list.elements == 1 && (!(thd->variables.option_bits & OPTION_WARNINGS) || !thd->cuted_fields)) { - thd->row_count_func= info.copied + info.deleted + - ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? - info.touched : info.updated); - my_ok(thd, (ulong) thd->row_count_func, id); + my_ok(thd, info.copied + info.deleted + + ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? + info.touched : info.updated), + id); } else { @@ -1024,8 +1024,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, (ulong) (info.deleted + updated), (ulong) thd->warning_info->statement_warn_count()); - thd->row_count_func= info.copied + info.deleted + updated; - ::my_ok(thd, (ulong) thd->row_count_func, id, buff); + ::my_ok(thd, info.copied + info.deleted + updated, id, buff); } thd->abort_on_warning= 0; DBUG_RETURN(FALSE); @@ -3337,7 +3336,7 @@ bool select_insert::send_eof() { int error; bool const trans_table= table->file->has_transactions(); - ulonglong id; + ulonglong id, row_count; bool changed; THD::killed_state killed_status= thd->killed; DBUG_ENTER("select_insert::send_eof"); @@ -3403,16 +3402,15 @@ bool select_insert::send_eof() sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, (ulong) (info.deleted+info.updated), (ulong) thd->warning_info->statement_warn_count()); - thd->row_count_func= info.copied + info.deleted + - ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? - info.touched : info.updated); - + row_count= info.copied + info.deleted + + ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? + info.touched : info.updated); id= (thd->first_successful_insert_id_in_cur_stmt > 0) ? thd->first_successful_insert_id_in_cur_stmt : (thd->arg_of_last_insert_id_function ? thd->first_successful_insert_id_in_prev_stmt : (info.copied ? autoinc_value_of_last_inserted_row : 0)); - ::my_ok(thd, (ulong) thd->row_count_func, id, buff); + ::my_ok(thd, row_count, id, buff); DBUG_RETURN(0); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1f53a7c7337..3c39a414e1f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -274,22 +274,20 @@ void init_update_queries(void) sql_command_flags[SQLCOM_CREATE_TRIGGER]= CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_DROP_TRIGGER]= CF_AUTO_COMMIT_TRANS; - sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT | - CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT | - CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT | - CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT | - CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT | - CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT | - CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL; - sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT | - CF_REEXECUTION_FRAGILE; - sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT | - CF_REEXECUTION_FRAGILE; + sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | + CF_PROTECT_AGAINST_GRL; + sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | + CF_PROTECT_AGAINST_GRL; + sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | + CF_PROTECT_AGAINST_GRL; + sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | + CF_PROTECT_AGAINST_GRL; + sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | + CF_PROTECT_AGAINST_GRL; + sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | + CF_PROTECT_AGAINST_GRL; + sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE; + sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE; sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE; sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE; @@ -367,8 +365,7 @@ void init_update_queries(void) last called (or executed) statement is preserved. See mysql_execute_command() for how CF_ROW_COUNT is used. */ - sql_command_flags[SQLCOM_CALL]= CF_HAS_ROW_COUNT | CF_REEXECUTION_FRAGILE; - sql_command_flags[SQLCOM_EXECUTE]= CF_HAS_ROW_COUNT; + sql_command_flags[SQLCOM_CALL]= CF_REEXECUTION_FRAGILE; /* The following admin table operations are allowed @@ -3184,7 +3181,7 @@ end_with_restore_list: res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values, lex->update_list, lex->value_list, lex->duplicates, lex->ignore); - MYSQL_INSERT_DONE(res, (ulong) thd->row_count_func); + MYSQL_INSERT_DONE(res, (ulong) thd->get_row_count_func()); /* If we have inserted into a VIEW, and the base table has AUTO_INCREMENT column, but this column is not accessible through @@ -3250,7 +3247,7 @@ end_with_restore_list: delete sel_result; } /* revert changes for SP */ - MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->row_count_func); + MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->get_row_count_func()); select_lex->table_list.first= (uchar*) first_table; } /* @@ -3296,7 +3293,7 @@ end_with_restore_list: &select_lex->order_list, unit->select_limit_cnt, select_lex->options, FALSE); - MYSQL_DELETE_DONE(res, (ulong) thd->row_count_func); + MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func()); break; } case SQLCOM_DELETE_MULTI: @@ -4299,8 +4296,9 @@ create_sp_error: thd->server_status&= ~bits_to_be_cleared; if (!res) - my_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 : - thd->row_count_func)); + { + my_ok(thd, (thd->get_row_count_func() < 0) ? 0 : thd->get_row_count_func()); + } else { DBUG_ASSERT(thd->is_error() || thd->killed); @@ -4687,15 +4685,6 @@ create_sp_error: if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION) reset_one_shot_variables(thd); - /* - The return value for ROW_COUNT() is "implementation dependent" if the - statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC - wants. We also keep the last value in case of SQLCOM_CALL or - SQLCOM_EXECUTE. - */ - if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT)) - thd->row_count_func= -1; - goto finish; error: diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc index 8ae77f3645b..8ba9cb369aa 100644 --- a/sql/sql_signal.cc +++ b/sql/sql_signal.cc @@ -458,8 +458,20 @@ bool Signal_statement::execute(THD *thd) DBUG_ENTER("Signal_statement::execute"); + /* + WL#2110 SIGNAL specification says: + + When SIGNAL is executed, it has five effects, in the following order: + + (1) First, the diagnostics area is completely cleared. So if the + SIGNAL is in a DECLARE HANDLER then any pending errors or warnings + are gone. So is 'row count'. + + This has roots in the SQL standard specification for SIGNAL. + */ + thd->stmt_da->reset_diagnostics_area(); - thd->row_count_func= 0; + thd->set_row_count_func(0); thd->warning_info->clear_warning_info(thd->query_id); result= raise_condition(thd, &cond); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 41737b33fb6..fb3a7605a94 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -843,9 +843,8 @@ int mysql_update(THD *thd, my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated, (ulong) thd->warning_info->statement_warn_count()); - thd->row_count_func= - (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; - my_ok(thd, (ulong) thd->row_count_func, id, buff); + my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, + id, buff); DBUG_PRINT("info",("%ld records updated", (long) updated)); } thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ @@ -2150,8 +2149,7 @@ bool multi_update::send_eof() thd->first_successful_insert_id_in_prev_stmt : 0; my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated, (ulong) thd->cuted_fields); - thd->row_count_func= - (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; - ::my_ok(thd, (ulong) thd->row_count_func, id, buff); + ::my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, + id, buff); DBUG_RETURN(FALSE); } |