Commit 7c4ceb73 authored by unknown's avatar unknown

WL#1567: Add ROW_COUNT() Function to retrieve count of rows updated/inserted/deleted


mysql-test/r/sp.result:
  New test cases for function ROW_COUNT().
mysql-test/t/sp.test:
  New test cases for function ROW_COUNT().
sql/item_func.cc:
  New Item_func_row_count.
sql/item_func.h:
  New Item_func_row_count.
sql/lex.h:
  New symbol for function ROW_COUNT().
sql/sql_class.h:
  New slot in THD for storing the row_count after insert, delete and update.
sql/sql_delete.cc:
  Set thd->row_count_func when deleting.
sql/sql_insert.cc:
  Set thd->row_count_func when inserting.
sql/sql_parse.cc:
  Stored procedure CALLs send the row count from the last insert, delete or update.
sql/sql_update.cc:
  Set thd->row_count_func when updating.
sql/sql_yacc.yy:
  New function ROW_COUNT().
parent 2eecc377
......@@ -802,6 +802,28 @@ use test|
drop database sp_db3|
select type,db,name from mysql.proc where db = 'sp_db3'|
type db name
create procedure rc()
begin
delete from t1;
insert into t1 values ("a", 1), ("b", 2), ("c", 3);
end|
call rc()|
select row_count()|
row_count()
3
update t1 set data=42 where id = "b";
select row_count()|
row_count()
1
delete from t1|
select row_count()|
row_count()
3
delete from t1|
select row_count()|
row_count()
0
drop procedure rc|
create procedure bug822(a_id char(16), a_data int)
begin
declare n int;
......
......@@ -931,6 +931,25 @@ drop database sp_db3|
select type,db,name from mysql.proc where db = 'sp_db3'|
# ROW_COUNT() function after a CALL
# We test the other cases here too, although it's not strictly SP specific
create procedure rc()
begin
delete from t1;
insert into t1 values ("a", 1), ("b", 2), ("c", 3);
end|
call rc()|
select row_count()|
update t1 set data=42 where id = "b";
select row_count()|
delete from t1|
select row_count()|
delete from t1|
select row_count()|
drop procedure rc|
#
# Test cases for old bugs
#
......
......@@ -3206,6 +3206,15 @@ longlong Item_func_is_used_lock::val_int()
}
longlong Item_func_row_count::val_int()
{
DBUG_ASSERT(fixed == 1);
THD *thd= current_thd;
return thd->row_count_func;
}
Item_func_sp::Item_func_sp(sp_name *name)
:Item_func(), m_name(name), m_sp(NULL)
{
......
......@@ -1076,6 +1076,16 @@ enum Cast_target
};
class Item_func_row_count :public Item_int_func
{
public:
Item_func_row_count() :Item_int_func() {}
longlong val_int();
const char *func_name() const { return "row_count"; }
void fix_length_and_dec() { decimals= 0; maybe_null=0; }
};
/*
*
* Stored FUNCTIONs
......
......@@ -681,6 +681,7 @@ static SYMBOL sql_functions[] = {
{ "RELEASE_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},
{ "REVERSE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)},
{ "ROUND", SYM(ROUND)},
{ "ROW_COUNT", SYM(ROW_COUNT_SYM)},
{ "RPAD", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)},
{ "RTRIM", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)},
{ "SEC_TO_TIME", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sec_to_time)},
......
......@@ -829,6 +829,7 @@ class THD :public ilink,
bool charset_is_system_charset, charset_is_collation_connection;
bool slow_command;
ulong row_count_func; /* For the ROW_COUNT() function */
sp_rcontext *spcont; // SP runtime context
sp_cache *sp_proc_cache;
sp_cache *sp_func_cache;
......
......@@ -96,6 +96,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order,
{
delete select;
free_underlaid_joins(thd, &thd->lex->select_lex);
thd->row_count_func= 0;
send_ok(thd,0L);
DBUG_RETURN(0); // Nothing to delete
}
......@@ -245,6 +246,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order,
send_error(thd,thd->killed_errno());
else
{
thd->row_count_func= deleted;
send_ok(thd,deleted);
DBUG_PRINT("info",("%d records deleted",deleted));
}
......@@ -550,7 +552,10 @@ bool multi_delete::send_eof()
if (local_error)
::send_error(thd);
else
{
thd->row_count_func= deleted;
::send_ok(thd, deleted);
}
return 0;
}
......
......@@ -419,7 +419,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
goto abort;
if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) ||
!thd->cuted_fields))
send_ok(thd,info.copied+info.deleted+info.updated,id);
{
thd->row_count_func= info.copied+info.deleted+info.updated;
send_ok(thd, thd->row_count_func, id);
}
else
{
char buff[160];
......@@ -430,7 +433,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
else
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) info.deleted+info.updated, (ulong) thd->cuted_fields);
::send_ok(thd,info.copied+info.deleted+info.updated,(ulonglong)id,buff);
thd->row_count_func= info.copied+info.deleted+info.updated;
::send_ok(thd, thd->row_count_func, (ulonglong)id,buff);
}
free_underlaid_joins(thd, &thd->lex->select_lex);
table->insert_values=0;
......@@ -1565,7 +1569,8 @@ bool select_insert::send_eof()
else
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) info.deleted+info.updated, (ulong) thd->cuted_fields);
::send_ok(thd,info.copied+info.deleted+info.updated,last_insert_id,buff);
thd->row_count_func= info.copied+info.deleted+info.updated;
::send_ok(thd, thd->row_count_func, last_insert_id, buff);
DBUG_RETURN(0);
}
......
......@@ -3582,7 +3582,7 @@ mysql_execute_command(THD *thd)
}
if (res == 0)
send_ok(thd);
send_ok(thd, thd->row_count_func);
else
goto error; // Substatement should already have sent error
}
......
......@@ -399,8 +399,9 @@ int mysql_update(THD *thd,
char buff[80];
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
(ulong) thd->cuted_fields);
send_ok(thd,
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
send_ok(thd, thd->row_count_func,
thd->insert_id_used ? thd->insert_id() : 0L,buff);
DBUG_PRINT("info",("%d records updated",updated));
}
......@@ -1124,8 +1125,9 @@ bool multi_update::send_eof()
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
(ulong) thd->cuted_fields);
::send_ok(thd,
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
::send_ok(thd, thd->row_count_func,
thd->insert_id_used ? thd->insert_id() : 0L,buff);
return 0;
}
......@@ -436,6 +436,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token X509_SYM
%token XOR
%token COMPRESSED_SYM
%token ROW_COUNT_SYM
%token ERRORS
%token WARNINGS
......@@ -3936,6 +3937,11 @@ simple_expr:
| ROUND '(' expr ')'
{ $$= new Item_func_round($3, new Item_int((char*)"0",0,1),0); }
| ROUND '(' expr ',' expr ')' { $$= new Item_func_round($3,$5,0); }
| ROW_COUNT_SYM '(' ')'
{
$$= new Item_func_row_count();
Lex->safe_to_cache_query= 0;
}
| SUBDATE_SYM '(' expr ',' expr ')'
{ $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 1);}
| SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
......
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