From: Nick Porter Date: Fri, 1 Apr 2022 14:31:36 +0000 (+0100) Subject: Fix handling of affected_rows for FreeTDS SQL driver X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=31dc5e30468ba2a5b2fb7eaa06e2141720441d8f;p=thirdparty%2Ffreeradius-server.git Fix handling of affected_rows for FreeTDS SQL driver After all the required calls to ct_results(), the internal counter of affected rows is reset. So, retrieve it whilst still available and store for later use. --- diff --git a/src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c b/src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c index e33f82b715f..2440aa30e4e 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c @@ -44,6 +44,7 @@ typedef struct { char **results; //!< Result strings from statement execution. char *error; //!< The last error string created by one of the call backs. bool established; //!< Set to false once the connection has been properly established. + CS_INT rows_affected; //!< Rows affected by last INSERT / UPDATE / DELETE. } rlm_sql_freetds_conn_t; #define MAX_DATASTR_LEN 256 @@ -198,6 +199,12 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c CS_RETCODE results_ret; CS_INT result_type; + /* + * Reset rows_affected in case the query fails. + * Prevents accidentally returning the rows_affected from a previous query. + */ + conn->rows_affected = -1; + if (ct_cmd_alloc(conn->db, &conn->command) != CS_SUCCEED) { ERROR("Unable to allocate command structure (ct_cmd_alloc())"); @@ -254,6 +261,17 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c } } + /* + * Retrieve the number of rows affected - the later calls + * to ct_results end up resetting the underlying counter so we + * no longer have access to this. + */ + if (ct_res_info(conn->command, CS_ROW_COUNT, &conn->rows_affected, CS_UNUSED, NULL) != CS_SUCCEED) { + ERROR("rlm_sql_freetds: error retrieving row count"); + + return RLM_SQL_ERROR; + } + /* * Second call to ct_results, we need returncode CS_SUCCEED * and result_type CS_CMD_DONE. @@ -553,15 +571,8 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) { rlm_sql_freetds_conn_t *conn = handle->conn; - int num; - if (ct_res_info(conn->command, CS_ROW_COUNT, (CS_INT *)&num, CS_UNUSED, NULL) != CS_SUCCEED) { - ERROR("error retrieving row count"); - - return RLM_SQL_ERROR; - } - - return num; + return (conn->rows_affected); } static sql_rcode_t sql_fetch_row(rlm_sql_row_t *out, rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) @@ -629,6 +640,7 @@ static sql_rcode_t sql_finish_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_con return RLM_SQL_ERROR; } conn->command = NULL; + conn->rows_affected = -1; return RLM_SQL_OK; }