Description:
Affects
https://dev.mysql.com/doc/refman/8.0/en/grant.html (13.7.1.6 GRANT Syntax)
https://dev.mysql.com/doc/refman/5.7/en/grant.html (13.7.1.4 GRANT Syntax)
https://dev.mysql.com/doc/refman/5.6/en/grant.html (13.7.1.4 GRANT Syntax)
https://dev.mysql.com/doc/refman/5.5/en/grant.html (13.7.1.3 GRANT Syntax)
Section 13.7.1.6 GRANT Syntax
Table 13.6 Permissible Static Privileges for GRANT and REVOKE
Entry for 'EXECUTE'
<snip>
Enable the user to execute stored routines. Levels: Global, database, table.
</snip>
Further down on the page where privileges relating to stored routines are explained it says:
<snip>
Stored Routine Privileges
The ALTER ROUTINE, CREATE ROUTINE, EXECUTE, and GRANT OPTION privileges apply to stored routines (procedures and functions). They can be granted at the global and database levels. Except for CREATE ROUTINE, these privileges can be granted at the routine level for individual routines.
GRANT CREATE ROUTINE ON mydb.* TO 'someuser'@'somehost';
GRANT EXECUTE ON PROCEDURE mydb.myproc TO 'someuser'@'somehost';
The permissible priv_type values at the routine level are ALTER ROUTINE, EXECUTE, and GRANT OPTION.
</snip>
Clearly indicating that EXECUTE can be granted at 'routine level', which is the case.
EXECUTE privilege can not be granted at the table level.
See definition for mysql.tables_priv
mysql> describe mysql.tables_priv;
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Table_name | char(64) | NO | PRI | | |
| Grantor | char(93) | NO | MUL | | |
| Timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| Table_priv | set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') | NO | | | |
| Column_priv | set('Select','Insert','Update','References') | NO | | | |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------+------+-----+-------------------+-----------------------------+
8 rows in set (0.00 sec)
So, 'table' should be replaced with 'routine'
How to repeat:
View pages
https://dev.mysql.com/doc/refman/8.0/en/grant.html (13.7.1.6 GRANT Syntax)
https://dev.mysql.com/doc/refman/5.7/en/grant.html (13.7.1.4 GRANT Syntax)
https://dev.mysql.com/doc/refman/5.6/en/grant.html (13.7.1.4 GRANT Syntax)
https://dev.mysql.com/doc/refman/5.5/en/grant.html (13.7.1.3 GRANT Syntax)
Table 13.6 Permissible Static Privileges for GRANT and REVOKE
Suggested fix:
Change text in Table 13.6 Permissible Static Privileges for GRANT and REVOKE
Change entry for 'EXECUTE' to
Enable the user to execute stored routines. Levels: Global, database, routine.