mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
WL#1567: Add ROW_COUNT() Function to retrieve count of rows updated/inserted/deleted
This commit is contained in:
@ -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 @@ public:
|
||||
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 @@ cleanup:
|
||||
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 @@ unsent_create_error:
|
||||
}
|
||||
|
||||
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 ')'
|
||||
|
Reference in New Issue
Block a user