Stored procedures in rlm_sql_mysql
Michael A Baikov
pacak at bk.ru
Wed May 16 22:30:12 CEST 2007
This patch allows me to use stored procedures in in sql.conf.
For example instead
authorize_check_query = "SELECT id, UserName, Attribute, Value, op \
FROM ${authcheck_table} \
WHERE Username = BINARY '%{SQL-User-Name}' \
ORDER BY id"
I can use
authorize_check_query = "CALL auth_check('%{SQL-User-Name}')"
and store all code in the database.
--------------------------------------
--- sql_mysql_orig.c 2007-04-05 14:52:38.000000000 +0400
+++ sql_mysql.c 2007-05-17 00:22:59.000000000 +0400
@@ -52,6 +52,9 @@
SQL_ROW row;
} rlm_sql_mysql_sock;
+/*static int sql_free_result(SQLSOCK*, SQL_CONFIG*); */
+
+
/*************************************************************************
*
* Function: sql_create_socket
@@ -84,7 +87,7 @@
config->sql_db,
atoi(config->sql_port),
NULL,
- CLIENT_FOUND_ROWS))) {
+ CLIENT_FOUND_ROWS|
CLIENT_MULTI_RESULTS))) {
radlog(L_ERR, "rlm_sql_mysql: Couldn't connect socket to MySQL
server %s@%s:%s", config->sql_login, config->sql_server, config->sql_db);
radlog(L_ERR, "rlm_sql_mysql: Mysql error '%s'",
mysql_error(&mysql_sock->conn));
mysql_sock->sock = NULL;
@@ -305,13 +308,35 @@
*************************************************************************/
static int sql_free_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
{
+ int status;
rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
if (mysql_sock->result) {
mysql_free_result(mysql_sock->result);
mysql_sock->result = NULL;
}
+
+ /*
+ * http://dev.mysql.com/doc/refman/5.0/en/c-api-multiple-queries.html
+ *
+ * Multiple-result processing also is required if you execute CALL
+ * statements for stored procedures: A stored procedure returns a
+ * status result when it terminates, but it may also produce result
+ * sets as it runs (for example, if it executes SELECT statements).
For
+ * any stored procedure that produces result sets in addition to the
+ * final status, you must be prepared to retrieve multiple results.
+ * */
+
+ status = mysql_next_result(mysql_sock);
+ while(status == 0) {
+ if ((status = mysql_next_result(mysql_sock)) > 0)
+ radlog(L_ERR, "rlm_sql_mysql: Error while fetching
next result in result set.");
+ /* I do not need them - just discard it */
+ radlog(L_DBG, "rlm_sql_mysql: Discarded an result from
multiple result request");
+ mysql_store_result(mysql_sock->sock);
+ }
return 0;
}
More information about the Freeradius-Devel
mailing list