Pregunta

Why am I unable to create this aggregate function?

As far as I can tell, I've granted the appropriate privileges (CREATE ROUTINE and ALTER ROUTINE) both on *.* and on my database (peacock):

mysql> SELECT User, Host, Create_priv, Create_routine_priv, Alter_routine_priv FROM mysql.user WHERE user='glpy';
+------+-----------+-------------+---------------------+--------------------+
| User | Host      | Create_priv | Create_routine_priv | Alter_routine_priv |
+------+-----------+-------------+---------------------+--------------------+
| glpy | localhost | Y           | Y                   | Y                  |
+------+-----------+-------------+---------------------+--------------------+

mysql> SELECT User, Host, db, Create_priv, Create_routine_priv, Alter_routine_priv FROM mysql.db WHERE user='glpy';
+------+-----------+---------+-------------+---------------------+--------------------+
| User | Host      | db      | Create_priv | Create_routine_priv | Alter_routine_priv |
+------+-----------+---------+-------------+---------------------+--------------------+
| glpy | localhost | peacock | N           | Y                   | Y                  |
+------+-----------+---------+-------------+---------------------+--------------------+

However, when I try to create the function, I get Access denied ... to database 'mysql':

mysql> use peacock;
mysql> CREATE AGGREGATE FUNCTION coverage RETURNS INT SONAME 'my-library.so';
ERROR 1044 (42000): Access denied for user 'glpy'@'localhost' to database 'mysql'

In particular:

  • Why is access required to the mysql table to create the aggregate function?
  • Given that I have granted the privileges on *.*, why is access denied?
  • I also tried granting the privileges on mysql, but access was still denied.
¿Fue útil?

Solución

CREATE [AGGREGATE] FUNCTION function_name 
RETURNS {STRING|INTEGER|REAL|DECIMAL}
SONAME shared_library_name;

This is the declaration for a User Defined Function, which appears to be what you are trying to install. This is not declaring a Stored Function. CREATE FUNCTION has two different uses in MySQL. This is one of them.

For this to work:

  • you do not need the CREATE ROUTINE privilege
  • it does not matter what database you're in, because User-Defined Functions, unlike stored functions, are global in scope. They extend MySQL functionality in a way that is analogous to its built-in aggregate functions, like AVG() and SUM() and MIN() and MAX().
  • you cannot specify a database as part of the function declaration
  • the following is the requirement that you are missing:

13.7.3.1. CREATE FUNCTION Syntax for User-Defined Functions

To create a function, you must have the INSERT privilege for the mysql database. This is necessary because CREATE FUNCTION adds a row to the mysql.func system table that records the function's name, type, and shared library name.

http://dev.mysql.com/doc/refman/5.6/en/create-function-udf.html

If you don't have this privilege, the function will have to be installed by someone who holds this privilege, or it will need to be granted to you. You can't grant it to yourself.

Otros consejos

From the manual:

CREATE PROCEDURE and CREATE FUNCTION require the CREATE ROUTINE privilege.

Make sure the privilege is on the database that you are trying to use. When you run CREATE AGGREGATE FUNCTION coverage RETURNS INT SONAME 'my-library.so';, you are trying to create the function in the mysql database (that is, the system database that is actually named mysql), so you need the CREATE ROUTINE privilege on that database. If you are trying to create it in some other database, run a USE my_database command or modify your syntax:

CREATE AGGREGATE FUNCTION my_database.coverage RETURNS INTEGER SONAME 'my-library.so';

If you are in a shared environment (pretty much anything other than a VPS or dedicated server), you probably don't have access to do anything to the mysql database and never will. So, create the function in your own database.

Edit: INT should be INTEGER.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top