diff --git a/0024-update-the-implementation-of-obtaining-the-last-resu.patch b/0024-update-the-implementation-of-obtaining-the-last-resu.patch new file mode 100644 index 0000000000000000000000000000000000000000..ddedd14eee4527a1a4672530b1bfdb016d3f3576 --- /dev/null +++ b/0024-update-the-implementation-of-obtaining-the-last-resu.patch @@ -0,0 +1,275 @@ +From 7fcec72723832a71c5bf4857c37664a764d88722 Mon Sep 17 00:00:00 2001 +From: motodiary +Date: Wed, 22 May 2024 17:04:57 +0800 +Subject: [PATCH] update the implementation of obtaining the last result set + +--- + src/database/pgsql_common.c | 109 +++++++++++++++++- + src/database/pgsql_common.h | 2 +- + .../accounting_storage/pgsql/as_pgsql_assoc.c | 20 ++-- + src/plugins/jobcomp/pgsql/jobcomp_pgsql.c | 2 +- + 4 files changed, 115 insertions(+), 18 deletions(-) + +diff --git a/src/database/pgsql_common.c b/src/database/pgsql_common.c +index cf5b78b..16d3315 100755 +--- a/src/database/pgsql_common.c ++++ b/src/database/pgsql_common.c +@@ -154,6 +154,33 @@ static void _get_last_result(SQLHSTMT stmt) + return ; + } + ++/* NOTE: Ensure that pgsql_conn->lock is set on function entry */ ++static void _get_result_by_index(SQLHSTMT stmt, int index) ++{ ++ SQLRETURN rc = 0; ++ int i = 1; // already at first result ++ ++ if (index <= 1) { ++ return ; ++ } ++ ++ while (i < index) { ++ rc = SQLMoreResults(stmt); ++ i++; ++ if (rc == SQL_NO_DATA) { ++ // arrive the last ++ error("too large index for current statement"); ++ break; ++ } else if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { ++ SQLCHAR state[PGSQL_STATE_LEN + 1]; ++ PGSQL_HANDLE_ERROR("SQLMorestmts", rc, SQL_HANDLE_STMT, stmt, state); ++ break; ++ } ++ } ++ ++ return ; ++} ++ + static void _parse_field_options(char* result, char* field_options) + { + xassert(str); +@@ -1151,10 +1178,9 @@ extern int pgsql_db_rollback(pgsql_conn_t *pgsql_conn) + return rc; + } + +- + /* NOTE: return pgsql_res_t and caller must free */ + extern pgsql_res_t* pgsql_db_query_ret(pgsql_conn_t *pgsql_conn, +- char *query, bool last) ++ char *query, int index) + { + pgsql_res_t* result = NULL; + slurm_mutex_lock(&pgsql_conn->lock); +@@ -1165,10 +1191,8 @@ extern pgsql_res_t* pgsql_db_query_ret(pgsql_conn_t *pgsql_conn, + } + + if (SLURM_SUCCESS == _pgsql_query_internal(pgsql_conn->db_conn, query, result->stmt, (SQLCHAR*)(result->state))) { +- if (last) { +- _get_last_result(result->stmt); +- debug4("_get_last_result for query:\n %s", query); +- } ++ ++ _get_result_by_index(result->stmt, index+1); + + SQLNumResultCols(result->stmt, &result->sNumCols); + SQLRETURN rc = SQLRowCount(result->stmt, &result->sNumRows); +@@ -1197,6 +1221,79 @@ fini: + return result; + } + ++/* NOTE: return pgsql_res_t and caller must free */ ++ extern pgsql_res_t* pgsql_db_query_last_ret(pgsql_conn_t *pgsql_conn, ++ char *query) ++ ++{ ++ SQLRETURN rc = SQL_SUCCESS; ++ pgsql_res_t* result = NULL; ++ slurm_mutex_lock(&pgsql_conn->lock); ++ ++ rc = _pgsql_query_internal(pgsql_conn->db_conn, query, result->stmt, (SQLCHAR*)(result->state)); ++ if (rc == SQL_SUCCESS) { ++ ++ while (1) { ++ ++ if (rc == SQL_NO_DATA) { ++ // arrive the last ++ break; ++ } else if (rc != SQL_SUCCESS) { ++ SQLCHAR state[PGSQL_STATE_LEN + 1]; ++ PGSQL_HANDLE_ERROR("SQLMoreResults", rc, SQL_HANDLE_STMT, result->stmt, state); ++ pgsql_free_result(&result); ++ goto fini; ++ } else { ++ ++ // init a new result ++ pgsql_free_result(&result); ++ _init_pgsql_res(&result, pgsql_conn); ++ if(result == NULL){ ++ goto fini; ++ } ++ ++ SQLNumResultCols(result->stmt, &result->sNumCols); ++ SQLRETURN rc = SQLRowCount(result->stmt, &result->sNumRows); ++ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { ++ SQLCHAR state[PGSQL_STATE_LEN + 1]; ++ PGSQL_HANDLE_ERROR("SQLRowCount", rc, SQL_HANDLE_STMT, result->stmt, state); ++ pgsql_free_result(&result); ++ goto fini; ++ } ++ ++ if (result->sNumRows > 0) { ++ result->rows = (pgsql_row*)malloc(result->sNumRows * sizeof(pgsql_row)); ++ if(result->rows == NULL) { ++ pgsql_free_result(&result); ++ goto fini; ++ } ++ for(int i = 0; i < result->sNumRows; i++) { ++ result->rows[i] = NULL; ++ } ++ } ++ ++ // save current result ++ while (pgsql_fetch_row(result)) { ++ // do nothing ++ } ++ ++ } ++ ++ // go to next result ++ rc = SQLMoreResults(result->stmt); ++ } ++ ++ } else { ++ pgsql_free_result(&result); ++ goto fini; ++ } ++ ++fini: ++ slurm_mutex_unlock(&pgsql_conn->lock); ++ ++ return result; ++} ++ + extern int pgsql_db_query_check_after(pgsql_conn_t *pgsql_conn, char *query) + { + int rc = SLURM_SUCCESS; +diff --git a/src/database/pgsql_common.h b/src/database/pgsql_common.h +index 82f8261..f828fe7 100755 +--- a/src/database/pgsql_common.h ++++ b/src/database/pgsql_common.h +@@ -160,7 +160,7 @@ extern int pgsql_db_commit(pgsql_conn_t *pgsql_conn); + extern int pgsql_db_rollback(pgsql_conn_t *pgsql_conn); + + extern pgsql_res_t* pgsql_db_query_ret(pgsql_conn_t *pgsql_conn, +- char *query, bool last); ++ char *query, int index); + extern int pgsql_db_query_check_after(pgsql_conn_t *pgsql_conn, char *query); + + extern int pgsql_db_query_stmt(pgsql_conn_t *pgsql_conn, +diff --git a/src/plugins/accounting_storage/pgsql/as_pgsql_assoc.c b/src/plugins/accounting_storage/pgsql/as_pgsql_assoc.c +index d198a95..4c7d7e3 100755 +--- a/src/plugins/accounting_storage/pgsql/as_pgsql_assoc.c ++++ b/src/plugins/accounting_storage/pgsql/as_pgsql_assoc.c +@@ -281,7 +281,7 @@ static int _reset_default_assoc(pgsql_conn_t *pgsql_conn, + assoc->cluster, assoc_table, + assoc->user, assoc->acct); + DB_DEBUG(DB_ASSOC, pgsql_conn->conn, "query\n%s", sel_query); +- result = pgsql_db_query_ret(pgsql_conn, sel_query, 1); ++ result = pgsql_db_query_ret(pgsql_conn, sel_query, 0); + if(!pgsql_db_match_state(pgsql_errno(result), SUCCESSFUL_COMPLETION)){ + xfree(sel_query); + pgsql_free_result(&result); +@@ -332,12 +332,12 @@ static int _check_coord_qos(pgsql_conn_t *pgsql_conn, char *cluster_name, + /* If there is a variable cleared here we need to make + sure we get the parent's information, if any. */ + query = xstrdup_printf( +- "call get_coord_qos('%s', '%s', '%s', '%s');", ++ "select get_coord_qos('%s', '%s', '%s', '%s');", + assoc_table, account, + cluster_name, coord_name); + debug4("%d(%s:%d) query\n%s", + pgsql_conn->conn, THIS_FILE, __LINE__, query); +- result = pgsql_db_query_ret(pgsql_conn, query, 1); ++ result = pgsql_db_query_ret(pgsql_conn, query, 0); + if(!pgsql_db_match_state(pgsql_errno(result), SUCCESSFUL_COMPLETION)){ + xfree(query); + pgsql_free_result(&result); +@@ -544,7 +544,7 @@ static int _move_account(pgsql_conn_t *pgsql_conn, uint32_t *lft, uint32_t *rgt, + "select lft, rgt from \"%s_%s\" where id_assoc = %s", + cluster, assoc_table, id); + DB_DEBUG(DB_ASSOC, pgsql_conn->conn, "query\n%s", query); +- result = pgsql_db_query_ret(pgsql_conn, query, 1); ++ result = pgsql_db_query_ret(pgsql_conn, query, 7); + if(!pgsql_db_match_state(pgsql_errno(result), SUCCESSFUL_COMPLETION)){ + xfree(query); + pgsql_free_result(&result); +@@ -659,7 +659,7 @@ static uint32_t _get_parent_id( + debug4("%d(%s:%d) query\n%s", + pgsql_conn->conn, THIS_FILE, __LINE__, query); + +- result = pgsql_db_query_ret(pgsql_conn, query, 1); ++ result = pgsql_db_query_ret(pgsql_conn, query, 0); + if(!pgsql_db_match_state(pgsql_errno(result), SUCCESSFUL_COMPLETION)){ + xfree(query); + pgsql_free_result(&result); +@@ -695,7 +695,7 @@ static int _set_assoc_lft_rgt( + debug4("%d(%s:%d) query\n%s", + pgsql_conn->conn, THIS_FILE, __LINE__, query); + +- result = pgsql_db_query_ret(pgsql_conn, query, 1); ++ result = pgsql_db_query_ret(pgsql_conn, query, 0); + if(!pgsql_db_match_state(pgsql_errno(result), SUCCESSFUL_COMPLETION)){ + xfree(query); + pgsql_free_result(&result); +@@ -740,7 +740,7 @@ static int _set_assoc_limits_for_add( + assoc_table, parent, assoc->cluster, 0); + debug4("%d(%s:%d) query\n%s", + pgsql_conn->conn, THIS_FILE, __LINE__, query); +- result = pgsql_db_query_ret(pgsql_conn, query, 1); ++ result = pgsql_db_query_ret(pgsql_conn, query, 0); + if(!pgsql_db_match_state(pgsql_errno(result), SUCCESSFUL_COMPLETION)){ + xfree(query); + pgsql_free_result(&result); +@@ -1477,7 +1477,7 @@ static int _process_modify_assoc_results(pgsql_conn_t *pgsql_conn, + cluster_name, 0); + debug4("%d(%s:%d) query\n%s", + pgsql_conn->conn, THIS_FILE, __LINE__, query); +- result2 = pgsql_db_query_ret(pgsql_conn, query, 1); ++ result2 = pgsql_db_query_ret(pgsql_conn, query, 0); + if(!pgsql_db_match_state(pgsql_errno(result2), SUCCESSFUL_COMPLETION)){ + xfree(query); + pgsql_free_result(&result2); +@@ -2134,7 +2134,7 @@ static int _cluster_get_assocs(pgsql_conn_t *pgsql_conn, + without_parent_limits); + debug4("%d(%s:%d) query\n%s", + pgsql_conn->conn, THIS_FILE, __LINE__, query); +- result2 = pgsql_db_query_ret(pgsql_conn, query, 1); ++ result2 = pgsql_db_query_ret(pgsql_conn, query, 0); + if(!pgsql_db_match_state(pgsql_errno(result2), SUCCESSFUL_COMPLETION)){ + xfree(query); + pgsql_free_result(&result2); +@@ -2547,7 +2547,7 @@ extern int as_pgsql_add_assocs(pgsql_conn_t *pgsql_conn, uint32_t uid, + object->user, object->acct); + DB_DEBUG(DB_ASSOC, pgsql_conn->conn, "query\n%s", + query); +- result = pgsql_db_query_ret(pgsql_conn, query, 1); ++ result = pgsql_db_query_ret(pgsql_conn, query, 0); + if(!pgsql_db_match_state(pgsql_errno(result), SUCCESSFUL_COMPLETION)){ + xfree(query); + rc = SLURM_ERROR; +diff --git a/src/plugins/jobcomp/pgsql/jobcomp_pgsql.c b/src/plugins/jobcomp/pgsql/jobcomp_pgsql.c +index 96aa8b7..1ec4588 100755 +--- a/src/plugins/jobcomp/pgsql/jobcomp_pgsql.c ++++ b/src/plugins/jobcomp/pgsql/jobcomp_pgsql.c +@@ -382,7 +382,7 @@ extern int jobcomp_p_log_record(job_record_t *job_ptr) + xstrfmtcat(on_dup, ", blockid='%s'", blockid); + xfree(blockid); + } +- xstrfmtcat(query, ") ON DUPLICATE KEY UPDATE %s;", on_dup); ++ xstrfmtcat(query, ") ON CONFLICT (jobid, starttime, endtime) DO UPDATE SET %s;", on_dup); + + debug3("(%s:%d) query\n%s", + THIS_FILE, __LINE__, query); +-- +2.33.0 + diff --git a/slurm.spec b/slurm.spec index f25147f1dfaeae9dfc95cefb9a2a9054299e4142..849022c4f0a6e13f8c501a18dbe2e53cf1e4d599 100644 --- a/slurm.spec +++ b/slurm.spec @@ -1,6 +1,6 @@ Name: slurm Version: 21.08.8 -%define rel 26 +%define rel 27 Release: %{rel}%{?dist} Summary: Slurm Workload Manager @@ -39,6 +39,7 @@ Patch20: 0020-replace-UNIX_TIMESTAMP-in-sql.patch Patch21: 0021-fix-user-and-partition-field-in-sql.patch Patch22: 0022-add-SQLRowCount-exception-handling.patch Patch23: 0023-modify-step-table.patch +Patch24: 0024-update-the-implementation-of-obtaining-the-last-resu.patch # build options .rpmmacros options change to default action # ==================== ==================== ======================== @@ -731,6 +732,9 @@ rm -rf %{buildroot} %systemd_postun_with_restart slurmdbd.service %changelog +* Wed May 22 2024 Xing Liu - 21.08.8-27 +- update the implementation of obtaining the last result set + * Wed May 22 2024 Xing Liu - 21.08.8-26 - modify step table