]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Fix handling of affected_rows for FreeTDS SQL driver
authorNick Porter <nick@portercomputing.co.uk>
Fri, 1 Apr 2022 14:31:36 +0000 (15:31 +0100)
committerNick Porter <nick@portercomputing.co.uk>
Mon, 4 Apr 2022 13:05:46 +0000 (14:05 +0100)
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.

src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c

index e33f82b715f46ea7bdca453ee837093156d285df..2440aa30e4e9740049b9a092be97d9f93e381a20 100644 (file)
@@ -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;
 }