Skip to content

Commit 2987242

Browse files
committed
Fix cache_empty_result=0 not caching non-empty resultsets (issue #5248)
The `cache_empty_result` field in query rules has three possible values: • -1: Use global setting (`query_cache_stores_empty_result`) • 0: Do NOT cache empty resultsets, but cache non-empty resultsets • 1: Always cache resultsets (both empty and non-empty) Previously, when `cache_empty_result` was set to 0, nothing was cached at all, even for non-empty resultsets. This prevented users from disabling caching for empty resultsets while still allowing caching of non-empty resultsets on a per-rule basis. Changes: 1. Modified caching logic in MySQL_Session.cpp and PgSQL_Session.cpp to add the condition `(qpo->cache_empty_result == 0 && MyRS->num_rows)` (MySQL) and `(qpo->cache_empty_result == 0 && num_rows)` (PgSQL) to allow caching when cache_empty_result=0 AND result has rows. 2. Added comprehensive Doxygen documentation in query_processor.h explaining the semantics of cache_empty_result values. 3. Updated Query_Processor.cpp with inline comments explaining the three possible values. Now when cache_empty_result is set to 0: - Empty resultsets (0 rows) are NOT cached - Non-empty resultsets (>0 rows) ARE cached - This matches the intended per-rule behavior described in issue #5248. Fixes: #5248
1 parent 8cf3e59 commit 2987242

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed

include/query_processor.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ typedef struct _Query_Processor_rule_t {
104104
char *replace_pattern;
105105
int destination_hostgroup;
106106
int cache_ttl;
107+
/** @brief Controls caching of empty resultsets for query rules
108+
*
109+
* Values:
110+
* - -1: Use global setting (query_cache_stores_empty_result)
111+
* - 0: Do NOT cache empty resultsets, but cache non-empty resultsets
112+
* - 1: Always cache resultsets (both empty and non-empty)
113+
*
114+
* Previously, setting cache_empty_result to 0 would prevent ALL caching,
115+
* even for non-empty resultsets. This was fixed in issue #5248.
116+
*/
107117
int cache_empty_result;
108118
int cache_timeout;
109119
int reconnect;
@@ -139,6 +149,16 @@ class Query_Processor_Output {
139149
int mirror_flagOUT;
140150
int next_query_flagIN;
141151
int cache_ttl;
152+
/** @brief Controls caching of empty resultsets for query rule output
153+
*
154+
* Values:
155+
* - -1: Use global setting (query_cache_stores_empty_result)
156+
* - 0: Do NOT cache empty resultsets, but cache non-empty resultsets
157+
* - 1: Always cache resultsets (both empty and non-empty)
158+
*
159+
* Previously, setting cache_empty_result to 0 would prevent ALL caching,
160+
* even for non-empty resultsets. This was fixed in issue #5248.
161+
*/
142162
int cache_empty_result;
143163
int cache_timeout;
144164
int reconnect;

lib/MySQL_Session.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7490,10 +7490,25 @@ void MySQL_Session::MySQL_Result_to_MySQL_wire(MYSQL *mysql, MySQL_ResultSet *My
74907490
if (transfer_started==false) { // we have all the resultset when MySQL_Result_to_MySQL_wire was called
74917491
if (qpo && qpo->cache_ttl>0 && com_field_list==false) { // the resultset should be cached
74927492
if (mysql_errno(mysql)==0 &&
7493-
(mysql_warning_count(mysql)==0 ||
7493+
(mysql_warning_count(mysql)==0 ||
74947494
mysql_thread___query_cache_handle_warnings==1)) { // no errors
7495+
/**
7496+
* @brief Check if the query result should be cached based on cache_empty_result setting
7497+
*
7498+
* The cache_empty_result field in query rule has three possible values:
7499+
* - 1: Always cache the result, regardless of whether it's empty or not
7500+
* - 0: Cache only non-empty results (num_rows > 0). Empty resultsets are not cached.
7501+
* - -1: Use global setting (thread->variables.query_cache_stores_empty_result)
7502+
* OR cache if result is non-empty (num_rows > 0)
7503+
*
7504+
* Previously, when cache_empty_result was set to 0, nothing was cached at all.
7505+
* This fix adds support for caching non-empty results when cache_empty_result=0.
7506+
*
7507+
* @see Issue #5248: Setting cache_empty_result to "0" on individual mysql_query_rules doesn't work
7508+
*/
74957509
if (
74967510
(qpo->cache_empty_result==1)
7511+
|| (qpo->cache_empty_result == 0 && MyRS->num_rows)
74977512
|| (
74987513
(qpo->cache_empty_result == -1)
74997514
&&

lib/PgSQL_Session.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4809,11 +4809,26 @@ void PgSQL_Session::PgSQL_Result_to_PgSQL_wire(PgSQL_Connection* _conn, PgSQL_Da
48094809
if (qpo && qpo->cache_ttl > 0 && is_tuple == true) { // the resultset should be cached
48104810

48114811
if (_conn->is_error_present() == false &&
4812-
(/* check warnings count here*/ true ||
4812+
(/* check warnings count here*/ true ||
48134813
pgsql_thread___query_cache_handle_warnings == 1)) { // no errors
48144814

4815+
/**
4816+
* @brief Check if the query result should be cached based on cache_empty_result setting
4817+
*
4818+
* The cache_empty_result field in query rule has three possible values:
4819+
* - 1: Always cache the result, regardless of whether it's empty or not
4820+
* - 0: Cache only non-empty results (num_rows > 0). Empty resultsets are not cached.
4821+
* - -1: Use global setting (thread->variables.query_cache_stores_empty_result)
4822+
* OR cache if result is non-empty (num_rows > 0)
4823+
*
4824+
* Previously, when cache_empty_result was set to 0, nothing was cached at all.
4825+
* This fix adds support for caching non-empty results when cache_empty_result=0.
4826+
*
4827+
* @see Issue #5248: Setting cache_empty_result to "0" on individual mysql_query_rules doesn't work
4828+
*/
48154829
if (
4816-
(qpo->cache_empty_result == 1) ||
4830+
(qpo->cache_empty_result == 1) ||
4831+
(qpo->cache_empty_result == 0 && num_rows) ||
48174832
(
48184833
(qpo->cache_empty_result == -1) &&
48194834
(thread->variables.query_cache_stores_empty_result || num_rows)

lib/Query_Processor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,10 @@ Query_Processor_Output* Query_Processor<QP_DERIVED>::process_query(TypeSession*
15591559
}
15601560
if (qr->cache_empty_result >= 0) {
15611561
// Note: negative value means this rule doesn't change
1562+
// cache_empty_result values:
1563+
// -1: Use global setting (query_cache_stores_empty_result)
1564+
// 0: Do NOT cache empty resultsets, but cache non-empty resultsets
1565+
// 1: Always cache resultsets (both empty and non-empty)
15621566
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has set cache_empty_result: %d. Query with empty result will%s hit the cache\n", qr->rule_id, qr->cache_empty_result, (qr->cache_empty_result == 0 ? " NOT" : "" ));
15631567
ret->cache_empty_result=qr->cache_empty_result;
15641568
}

0 commit comments

Comments
 (0)