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|
|
drop database sp_db3|
|
||||||
select type,db,name from mysql.proc where db = 'sp_db3'|
|
select type,db,name from mysql.proc where db = 'sp_db3'|
|
||||||
type db name
|
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)
|
create procedure bug822(a_id char(16), a_data int)
|
||||||
begin
|
begin
|
||||||
declare n int;
|
declare n int;
|
||||||
|
@ -931,6 +931,25 @@ drop database sp_db3|
|
|||||||
select type,db,name from mysql.proc where db = '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
|
# 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_sp::Item_func_sp(sp_name *name)
|
||||||
:Item_func(), m_name(name), m_sp(NULL)
|
: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
|
* Stored FUNCTIONs
|
||||||
|
@ -681,6 +681,7 @@ static SYMBOL sql_functions[] = {
|
|||||||
{ "RELEASE_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},
|
{ "RELEASE_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},
|
||||||
{ "REVERSE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)},
|
{ "REVERSE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)},
|
||||||
{ "ROUND", SYM(ROUND)},
|
{ "ROUND", SYM(ROUND)},
|
||||||
|
{ "ROW_COUNT", SYM(ROW_COUNT_SYM)},
|
||||||
{ "RPAD", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)},
|
{ "RPAD", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)},
|
||||||
{ "RTRIM", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)},
|
{ "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)},
|
{ "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 charset_is_system_charset, charset_is_collation_connection;
|
||||||
bool slow_command;
|
bool slow_command;
|
||||||
|
|
||||||
|
ulong row_count_func; /* For the ROW_COUNT() function */
|
||||||
sp_rcontext *spcont; // SP runtime context
|
sp_rcontext *spcont; // SP runtime context
|
||||||
sp_cache *sp_proc_cache;
|
sp_cache *sp_proc_cache;
|
||||||
sp_cache *sp_func_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;
|
delete select;
|
||||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||||
|
thd->row_count_func= 0;
|
||||||
send_ok(thd,0L);
|
send_ok(thd,0L);
|
||||||
DBUG_RETURN(0); // Nothing to delete
|
DBUG_RETURN(0); // Nothing to delete
|
||||||
}
|
}
|
||||||
@ -245,6 +246,7 @@ cleanup:
|
|||||||
send_error(thd,thd->killed_errno());
|
send_error(thd,thd->killed_errno());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
thd->row_count_func= deleted;
|
||||||
send_ok(thd,deleted);
|
send_ok(thd,deleted);
|
||||||
DBUG_PRINT("info",("%d records deleted",deleted));
|
DBUG_PRINT("info",("%d records deleted",deleted));
|
||||||
}
|
}
|
||||||
@ -550,7 +552,10 @@ bool multi_delete::send_eof()
|
|||||||
if (local_error)
|
if (local_error)
|
||||||
::send_error(thd);
|
::send_error(thd);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
thd->row_count_func= deleted;
|
||||||
::send_ok(thd, deleted);
|
::send_ok(thd, deleted);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +419,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
goto abort;
|
goto abort;
|
||||||
if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) ||
|
if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) ||
|
||||||
!thd->cuted_fields))
|
!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
|
else
|
||||||
{
|
{
|
||||||
char buff[160];
|
char buff[160];
|
||||||
@ -430,7 +433,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
else
|
else
|
||||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||||
(ulong) info.deleted+info.updated, (ulong) thd->cuted_fields);
|
(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);
|
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||||
table->insert_values=0;
|
table->insert_values=0;
|
||||||
@ -1565,7 +1569,8 @@ bool select_insert::send_eof()
|
|||||||
else
|
else
|
||||||
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
|
||||||
(ulong) info.deleted+info.updated, (ulong) thd->cuted_fields);
|
(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);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3582,7 +3582,7 @@ unsent_create_error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
send_ok(thd);
|
send_ok(thd, thd->row_count_func);
|
||||||
else
|
else
|
||||||
goto error; // Substatement should already have sent error
|
goto error; // Substatement should already have sent error
|
||||||
}
|
}
|
||||||
|
@ -399,8 +399,9 @@ int mysql_update(THD *thd,
|
|||||||
char buff[80];
|
char buff[80];
|
||||||
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
|
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
|
||||||
(ulong) thd->cuted_fields);
|
(ulong) thd->cuted_fields);
|
||||||
send_ok(thd,
|
thd->row_count_func=
|
||||||
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
|
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
|
||||||
|
send_ok(thd, thd->row_count_func,
|
||||||
thd->insert_id_used ? thd->insert_id() : 0L,buff);
|
thd->insert_id_used ? thd->insert_id() : 0L,buff);
|
||||||
DBUG_PRINT("info",("%d records updated",updated));
|
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,
|
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
|
||||||
(ulong) thd->cuted_fields);
|
(ulong) thd->cuted_fields);
|
||||||
::send_ok(thd,
|
thd->row_count_func=
|
||||||
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
|
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
|
||||||
|
::send_ok(thd, thd->row_count_func,
|
||||||
thd->insert_id_used ? thd->insert_id() : 0L,buff);
|
thd->insert_id_used ? thd->insert_id() : 0L,buff);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -436,6 +436,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
%token X509_SYM
|
%token X509_SYM
|
||||||
%token XOR
|
%token XOR
|
||||||
%token COMPRESSED_SYM
|
%token COMPRESSED_SYM
|
||||||
|
%token ROW_COUNT_SYM
|
||||||
|
|
||||||
%token ERRORS
|
%token ERRORS
|
||||||
%token WARNINGS
|
%token WARNINGS
|
||||||
@ -3936,6 +3937,11 @@ simple_expr:
|
|||||||
| ROUND '(' expr ')'
|
| ROUND '(' expr ')'
|
||||||
{ $$= new Item_func_round($3, new Item_int((char*)"0",0,1),0); }
|
{ $$= new Item_func_round($3, new Item_int((char*)"0",0,1),0); }
|
||||||
| ROUND '(' expr ',' expr ')' { $$= new Item_func_round($3,$5,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 ')'
|
| SUBDATE_SYM '(' expr ',' expr ')'
|
||||||
{ $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 1);}
|
{ $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 1);}
|
||||||
| SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
|
| SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
|
||||||
|
Reference in New Issue
Block a user