Skip to content

feat: per-hostgroup query timeouts.#5772

Open
burnison wants to merge 3 commits into
sysown:v3.0from
burnison:hostgroup_attribute_timeouts
Open

feat: per-hostgroup query timeouts.#5772
burnison wants to merge 3 commits into
sysown:v3.0from
burnison:hostgroup_attribute_timeouts

Conversation

@burnison

@burnison burnison commented May 13, 2026

Copy link
Copy Markdown

We have a use-case where we'd want to set query timeouts on a per-hostgroup basis. This is currently only possible globally or by using query rules, but I'd like to be able to handle this in constant-time and without having to pin the rule to a specific user.

This change adds a default_query_timeout JSON pseudo-attribute in the mysql_hostgroup_attributes.hostgroup_settings column, which will override the global default, but will, itself, be overridden by a rule.

INSERT INTO mysql_hostgroup_attributes (hostgroup_id, hostgroup_settings)
VALUES (100, '{"default_query_timeout": 8000}');

LOAD MYSQL SERVERS TO RUNTIME;

Summary by CodeRabbit

  • New Features

    • Per-hostgroup default query timeout (hostgroup_settings.default_query_timeout) for MySQL and PostgreSQL; validated, stored per-hostgroup, and enforced at runtime with precedence: per-rule > per-hostgroup > global.
  • Behavior

    • Hostgroup default can be unset/disabled and falls back to global; invalid values are rejected and cause fallback.
  • Tests

    • New integration tests covering precedence, validation/range handling, runtime application, persistence, and cleanup/restoration.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a hostgroup-level default_query_timeout attribute, parses it from hostgroup JSON for MySQL and PostgreSQL, applies it during session timeout setup before global defaults when unset, and adds TAP tests plus test-group mappings validating precedence (rule > hostgroup > global).

Changes

Hostgroup-level Query Timeout Override

Layer / File(s) Summary
Base data model and attribute initialization
include/Base_HostGroups_Manager.h, lib/BaseHGC.cpp
The BaseHGC::attributes struct adds int32_t default_query_timeout and initializes it to -1.
MySQL hostgroup parsing and runtime application
lib/MySQL_HostGroups_Manager.cpp, lib/MySQL_Session.cpp
Parses mysql_hostgroup_attributes.hostgroup_settings.default_query_timeout into myhgc->attributes.default_query_timeout, with bounds validation; MySQL_Session::SetQueryTimeout() applies this hostgroup override when wait_until is unset, before global fallback.
PostgreSQL hostgroup parsing and runtime application
lib/PgSQL_HostGroups_Manager.cpp, lib/PgSQL_Session.cpp
Parses default_query_timeout from PGSQL hostgroup settings into myhgc->attributes.default_query_timeout with validated range; PgSQL_Session::SetQueryTimeout() applies this hostgroup override when wait_until is unset, before global fallback.
Test configuration and group mappings
test/tap/groups/groups.json
Registers test_hostgroup_default_query_timeout-t and pgsql-hostgroup_default_query_timeout-t test groups.
PostgreSQL hostgroup timeout precedence and behavior test
test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
TAP integration test exercises precedence cases, surgical runtime edits, JSON parsing/roundtrip checks, and cleanup for PostgreSQL.
MySQL hostgroup timeout precedence and behavior test
test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
TAP integration test exercises precedence cases, surgical runtime edits, JSON parsing/roundtrip checks, and cleanup for MySQL.

Sequence Diagram (high-level request flow):

sequenceDiagram
  participant Client
  participant ProxySQL
  participant Admin as ProxyAdmin
  participant DB

  Client->>ProxySQL: Execute query
  ProxySQL->>ProxySQL: Determine timeout (check per-rule timeout)
  alt no per-rule
    ProxySQL->>ProxySQL: Check hostgroup default_query_timeout
  else no hostgroup override
    ProxySQL->>ProxySQL: Use global default timeout
  end
  ProxySQL->>DB: Forward query with applied timeout
  Admin->>ProxySQL: (tests) update hostgroup settings / query_rules / globals
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • renecannao

Poem

🐰 I nibble code and count each hop,
Rule wins first, then hostgroup stop,
If hostgroup sleeps, the global wakes,
Tests poke JSON for the stakes,
— The Review Rabbit 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: per-hostgroup query timeouts' accurately and concisely describes the main change: adding a new per-hostgroup query timeout feature across MySQL and PostgreSQL hostgroup managers and sessions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a per-hostgroup default_query_timeout setting for MySQL and PostgreSQL, allowing for more granular control over query execution limits. The changes include updates to hostgroup attribute structures, JSON parsing logic, and session-level timeout enforcement, alongside new TAP tests for both protocols. Review feedback highlighted potential null pointer dereferences in the session logic when accessing hostgroup attributes through the connection chain, recommending defensive null checks to prevent segmentation faults.

Comment thread lib/MySQL_Session.cpp
Comment thread lib/PgSQL_Session.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/PgSQL_HostGroups_Manager.cpp`:
- Around line 3805-3808: The validation for default_query_timeout is using
PgSQL_j_get_srv_default_int_val which logs errors under
pgsql_hostgroup_attributes.servers_defaults.*, but the JSON key comes from
hostgroup_settings; update the call so validation errors reference
hostgroup_settings instead: modify the invocation of
PgSQL_j_get_srv_default_int_val (or its wrapper) to pass the correct
context/path for logging (or use the overload that accepts a custom json-path
label) when reading "default_query_timeout", keeping the existing
default_query_timeout_check and assignment to
myhgc->attributes.default_query_timeout unchanged.

In `@lib/PgSQL_Session.cpp`:
- Around line 2765-2767: The read of attributes.default_query_timeout in
SetQueryTimeout() races with admin reload writes; either make the field
std::atomic<int32_t> (change myhgc->attributes.default_query_timeout to
std::atomic<int32_t> and use .load(std::memory_order_relaxed) in
SetQueryTimeout() and .store(...) with a matching memory order in
generate_pgsql_hostgroup_attributes_table()) or protect both the reader
(SetQueryTimeout) and the writer (generate_pgsql_hostgroup_attributes_table
called under wrlock()) with the same lock; update the read at the
SetQueryTimeout site to use .load(...) or acquire the lock accordingly and
update the write path to use .store(...) if switching to atomic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 70f0b5d0-95ac-4fa7-8641-e8db2c57c76b

📥 Commits

Reviewing files that changed from the base of the PR and between 9cc20a8 and 0fa9734.

📒 Files selected for processing (9)
  • include/Base_HostGroups_Manager.h
  • lib/BaseHGC.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • lib/MySQL_Session.cpp
  • lib/PgSQL_HostGroups_Manager.cpp
  • lib/PgSQL_Session.cpp
  • test/tap/groups/groups.json
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names must use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)
Member variables must use snake_case naming convention
Constants and macros must use UPPER_SNAKE_CASE naming convention
Use conditional compilation via #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, #ifdef PROXYSQLCLICKHOUSE for feature tier gating in core code

Files:

  • lib/BaseHGC.cpp
  • lib/PgSQL_Session.cpp
  • lib/MySQL_Session.cpp
  • lib/PgSQL_HostGroups_Manager.cpp
  • include/Base_HostGroups_Manager.h
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
**/*.{h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

Include guards in header files must use #ifndef __CLASS_*_H pattern

Files:

  • include/Base_HostGroups_Manager.h
test/tap/tests/{test_*,-t}.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Test files must follow the naming pattern test_*.cpp or *-t.cpp in test/tap/tests/

Files:

  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
test/tap/tests/*-t.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Test binaries are built via pattern rule in test/tap/tests/Makefile: make <testname>-t compiles <testname>-t.cpp into <testname>-t without requiring explicit Makefile targets

Files:

  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
🧠 Learnings (1)
📚 Learning: 2026-01-20T09:34:19.124Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:39-48
Timestamp: 2026-01-20T09:34:19.124Z
Learning: In ProxySQL's TAP test suite, resource leaks (e.g., not calling mysql_close() on early return paths) are commonly tolerated because test processes are short-lived and OS frees resources on exit. This pattern applies to all C++ test files under test/tap/tests. When reviewing, recognize this as a project-wide test convention and focus on test correctness and isolation rather than insisting on fixing such leaks in these test files.

Applied to files:

  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
🔇 Additional comments (8)
include/Base_HostGroups_Manager.h (1)

313-313: LGTM!

lib/BaseHGC.cpp (1)

74-74: LGTM!

lib/MySQL_HostGroups_Manager.cpp (2)

5912-5914: LGTM!


5938-5941: LGTM!

lib/MySQL_Session.cpp (1)

4749-4757: LGTM!

test/tap/groups/groups.json (1)

370-371: LGTM!

test/tap/tests/test_hostgroup_default_query_timeout-t.cpp (1)

1-323: LGTM!

test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp (1)

1-311: LGTM!

Comment thread lib/PgSQL_HostGroups_Manager.cpp
Comment thread lib/PgSQL_Session.cpp
@renecannao

Copy link
Copy Markdown
Contributor

Hi @burnison .
You can already achieve the same using query rules.
Is there a strong reason to implement a new feature for reaching the same goal?
I imagine it makes sense when not using query rules at all and relying only on default hostgroup on a per user basis, but unless a large number of users need dedicated timeout, adding query rules seems an easy configuration (and easy to debug too).

@burnison burnison force-pushed the hostgroup_attribute_timeouts branch from 0fa9734 to b0c0321 Compare May 13, 2026 02:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp (1)

237-261: 💤 Low value

Early return EXIT_FAILURE paths skip cleanup of already-applied runtime mutations.

Once pgsql-default_query_timeout has been updated and loaded to runtime (lines 237-240), any subsequent admin_exec failure in lines 243-261 returns EXIT_FAILURE without running the restore block at 308-320, leaving the global variable and (potentially) the hostgroup attributes row modified for the next test. Consider using a small RAII guard or a goto cleanup; pattern so partial-progress failures still hit the restore path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp` around lines 237
- 261, The test currently returns EXIT_FAILURE directly from multiple admin_exec
calls (e.g., the calls that set GLOBAL_TIMEOUT_MS, LOAD PGSQL VARIABLES TO
RUNTIME, and subsequent INSERT/DELETE statements around hg_override,
RULE_ID_BASE, RULE_TIMEOUT_MS), which skips the restore block and leaves runtime
state modified; change the flow so any failure after the initial runtime
mutation jumps to a single cleanup/restore path (for example add an RAII guard
that tracks “applied_runtime_changes” and restores on destruction, or replace
early returns with setting an error flag and goto cleanup;) ensuring admin_exec
failures still execute the existing restore logic that resets
pgsql-default_query_timeout and removes/rewrites pgsql_hostgroup_attributes and
pgsql_query_rules.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp`:
- Around line 227-234: The test only snapshots pgsql-default_query_timeout but
not the pgsql_hostgroup_attributes row for the discovered override hostgroup
(hg_override), so the DELETE removes a pre-existing row and the restore block
does not re-insert it; add code to query and save the entire
pgsql_hostgroup_attributes row for hg_override before the DELETE (e.g., into a
saved_hostgroup_row string), and in the restore/exit block recreate or re-insert
that row if non-empty (or DELETE only if it was absent originally) using the
same admin SQL helper functions used elsewhere; after restoring/re-inserting the
row, call the existing servers reload routine so runtime reflects the restored
state.

---

Nitpick comments:
In `@test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp`:
- Around line 237-261: The test currently returns EXIT_FAILURE directly from
multiple admin_exec calls (e.g., the calls that set GLOBAL_TIMEOUT_MS, LOAD
PGSQL VARIABLES TO RUNTIME, and subsequent INSERT/DELETE statements around
hg_override, RULE_ID_BASE, RULE_TIMEOUT_MS), which skips the restore block and
leaves runtime state modified; change the flow so any failure after the initial
runtime mutation jumps to a single cleanup/restore path (for example add an RAII
guard that tracks “applied_runtime_changes” and restores on destruction, or
replace early returns with setting an error flag and goto cleanup;) ensuring
admin_exec failures still execute the existing restore logic that resets
pgsql-default_query_timeout and removes/rewrites pgsql_hostgroup_attributes and
pgsql_query_rules.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f6494533-c734-4840-b806-b3e05c5c8123

📥 Commits

Reviewing files that changed from the base of the PR and between 0fa9734 and b0c0321.

📒 Files selected for processing (9)
  • include/Base_HostGroups_Manager.h
  • lib/BaseHGC.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • lib/MySQL_Session.cpp
  • lib/PgSQL_HostGroups_Manager.cpp
  • lib/PgSQL_Session.cpp
  • test/tap/groups/groups.json
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
🚧 Files skipped from review as they are similar to previous changes (6)
  • lib/BaseHGC.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • lib/PgSQL_HostGroups_Manager.cpp
  • test/tap/groups/groups.json
  • lib/MySQL_Session.cpp
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names must use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)
Member variables must use snake_case naming convention
Constants and macros must use UPPER_SNAKE_CASE naming convention
Use conditional compilation via #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, #ifdef PROXYSQLCLICKHOUSE for feature tier gating in core code

Files:

  • include/Base_HostGroups_Manager.h
  • lib/PgSQL_Session.cpp
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
**/*.{h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

Include guards in header files must use #ifndef __CLASS_*_H pattern

Files:

  • include/Base_HostGroups_Manager.h
test/tap/tests/*-t.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Test binaries are built via pattern rule in test/tap/tests/Makefile: make <testname>-t compiles <testname>-t.cpp into <testname>-t without requiring explicit Makefile targets

Files:

  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
🔇 Additional comments (2)
include/Base_HostGroups_Manager.h (1)

313-313: LGTM!

lib/PgSQL_Session.cpp (1)

2766-2770: Unresolved race on default_query_timeout read in SetQueryTimeout().

This read path is still unsynchronized while admin reload can update the same field concurrently; this is the same unresolved issue previously reported in this PR thread.

Comment thread test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
@burnison

Copy link
Copy Markdown
Author

@renecannao, the use-case we're trying to solve here is a number of users that share a common hostgroup that has a significantly higher query timeout threshold than the rest of the fleet (eg. a batch job replica pool).

This hostgroup also has a non-negligible number of users being routed to it, in some cases by rules, but mostly by default hostgroup. There's no other way we could determine to affect query timeouts to all queries on the hostgroup beside creating rules for each individual user.

Managing and maintaining such rules create a maintenance problem and creates risk of forgetting to create related rules for each individual user when new ones are added or when users are replaced.

@burnison burnison force-pushed the hostgroup_attribute_timeouts branch from b0c0321 to b7784f1 Compare May 13, 2026 03:13

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
test/tap/tests/test_hostgroup_default_query_timeout-t.cpp (2)

223-224: 💤 Low value

Consider escaping cl.username for defensive coding.

Although cl.username comes from environment variables (presumably trusted), directly concatenating it into SQL is a potential injection risk. For consistency with the restoration code (which uses mysql_real_escape_string for saved_hg_settings), consider escaping the username as well.

🛡️ Defensive fix using mysql_real_escape_string
+	std::vector<char> escaped_user(strlen(cl.username) * 2 + 1);
+	mysql_real_escape_string(admin, escaped_user.data(), cl.username, strlen(cl.username));
 	const string q = string("SELECT default_hostgroup FROM mysql_users WHERE username = '")
-		+ cl.username + "' LIMIT 1";
+		+ escaped_user.data() + "' LIMIT 1";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/tap/tests/test_hostgroup_default_query_timeout-t.cpp` around lines 223 -
224, The SQL query builds q by concatenating cl.username directly, which risks
injection; before constructing q, allocate a buffer and call
mysql_real_escape_string on cl.username (using the existing MYSQL* connection
used elsewhere), then use the escaped username when building q (replace direct
use of cl.username in the string construction). Ensure you size the buffer to at
least (strlen(cl.username) * 2 + 1) and reference mysql_real_escape_string and q
to locate the change.

292-292: 💤 Low value

Comment uses "SELECT SLEEP" but code uses "DO SLEEP".

The comment says "SELECT SLEEP(5)" but the actual query is "DO SLEEP(5)". Update the comment for consistency.

📝 Proposed fix
-	// SELECT SLEEP(5) > global 3s but < hostgroup override 8s: must complete.
+	// DO SLEEP(5) > global 3s but < hostgroup override 8s: must complete.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/tap/tests/test_hostgroup_default_query_timeout-t.cpp` at line 292,
Update the mismatched test comment so it reflects the actual query used: change
the comment that says "SELECT SLEEP(5)" to "DO SLEEP(5)" (or otherwise mention
"DO SLEEP(5) > global 3s but < hostgroup override 8s") so the comment and the
executed query in test_hostgroup_default_query_timeout-t.cpp are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/tap/tests/test_hostgroup_default_query_timeout-t.cpp`:
- Around line 223-224: The SQL query builds q by concatenating cl.username
directly, which risks injection; before constructing q, allocate a buffer and
call mysql_real_escape_string on cl.username (using the existing MYSQL*
connection used elsewhere), then use the escaped username when building q
(replace direct use of cl.username in the string construction). Ensure you size
the buffer to at least (strlen(cl.username) * 2 + 1) and reference
mysql_real_escape_string and q to locate the change.
- Line 292: Update the mismatched test comment so it reflects the actual query
used: change the comment that says "SELECT SLEEP(5)" to "DO SLEEP(5)" (or
otherwise mention "DO SLEEP(5) > global 3s but < hostgroup override 8s") so the
comment and the executed query in test_hostgroup_default_query_timeout-t.cpp are
consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 381c78d7-23b8-41e3-9d0f-63424c4e10de

📥 Commits

Reviewing files that changed from the base of the PR and between b0c0321 and b7784f1.

📒 Files selected for processing (9)
  • include/Base_HostGroups_Manager.h
  • lib/BaseHGC.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • lib/MySQL_Session.cpp
  • lib/PgSQL_HostGroups_Manager.cpp
  • lib/PgSQL_Session.cpp
  • test/tap/groups/groups.json
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
✅ Files skipped from review due to trivial changes (1)
  • lib/BaseHGC.cpp
🚧 Files skipped from review as they are similar to previous changes (7)
  • include/Base_HostGroups_Manager.h
  • lib/PgSQL_HostGroups_Manager.cpp
  • lib/PgSQL_Session.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • lib/MySQL_Session.cpp
  • test/tap/groups/groups.json
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names must use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)
Member variables must use snake_case naming convention
Constants and macros must use UPPER_SNAKE_CASE naming convention
Use conditional compilation via #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, #ifdef PROXYSQLCLICKHOUSE for feature tier gating in core code

Files:

  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
test/tap/tests/{test_*,-t}.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Test files must follow the naming pattern test_*.cpp or *-t.cpp in test/tap/tests/

Files:

  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
test/tap/tests/*-t.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Test binaries are built via pattern rule in test/tap/tests/Makefile: make <testname>-t compiles <testname>-t.cpp into <testname>-t without requiring explicit Makefile targets

Files:

  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
🧠 Learnings (1)
📚 Learning: 2026-01-20T09:34:19.124Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:39-48
Timestamp: 2026-01-20T09:34:19.124Z
Learning: In ProxySQL's TAP test suite, resource leaks (e.g., not calling mysql_close() on early return paths) are commonly tolerated because test processes are short-lived and OS frees resources on exit. This pattern applies to all C++ test files under test/tap/tests. When reviewing, recognize this as a project-wide test convention and focus on test correctness and isolation rather than insisting on fixing such leaks in these test files.

Applied to files:

  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
🔇 Additional comments (8)
test/tap/tests/test_hostgroup_default_query_timeout-t.cpp (8)

41-56: LGTM!


58-90: LGTM!


94-109: LGTM!


111-142: LGTM!


144-168: LGTM!


170-201: LGTM!


256-289: LGTM!


309-370: LGTM!

@burnison burnison force-pushed the hostgroup_attribute_timeouts branch from b7784f1 to 218796c Compare May 14, 2026 18:24

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
lib/PgSQL_HostGroups_Manager.cpp (1)

3805-3808: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Misleading error source path for default_query_timeout validation.

The validation uses PgSQL_j_get_srv_default_int_val which logs errors as pgsql_hostgroup_attributes.servers_defaults.default_query_timeout, but this field is actually read from hostgroup_settings (as documented in lines 3784-3786). This makes runtime diagnostics confusing when validation fails.

The same issue affects handle_warnings on line 3802.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/PgSQL_HostGroups_Manager.cpp` around lines 3805 - 3808, The
validation/error logging for default_query_timeout and handle_warnings
incorrectly attributes errors to pgsql_hostgroup_attributes.servers_defaults;
update the calls that use PgSQL_j_get_srv_default_int_val (for
default_query_timeout) and the call that validates handle_warnings so they
reference the correct JSON path "hostgroup_settings.<field>" (e.g.,
"hostgroup_settings.default_query_timeout" and
"hostgroup_settings.handle_warnings") or use the variant/parameter of
PgSQL_j_get_srv_default_int_val that allows supplying the explicit source path,
and then assign the result to myhgc->attributes.default_query_timeout as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@lib/PgSQL_HostGroups_Manager.cpp`:
- Around line 3805-3808: The validation/error logging for default_query_timeout
and handle_warnings incorrectly attributes errors to
pgsql_hostgroup_attributes.servers_defaults; update the calls that use
PgSQL_j_get_srv_default_int_val (for default_query_timeout) and the call that
validates handle_warnings so they reference the correct JSON path
"hostgroup_settings.<field>" (e.g., "hostgroup_settings.default_query_timeout"
and "hostgroup_settings.handle_warnings") or use the variant/parameter of
PgSQL_j_get_srv_default_int_val that allows supplying the explicit source path,
and then assign the result to myhgc->attributes.default_query_timeout as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 416c3bb3-525a-4335-93b3-06933f12a761

📥 Commits

Reviewing files that changed from the base of the PR and between b7784f1 and 218796c.

📒 Files selected for processing (9)
  • include/Base_HostGroups_Manager.h
  • lib/BaseHGC.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • lib/MySQL_Session.cpp
  • lib/PgSQL_HostGroups_Manager.cpp
  • lib/PgSQL_Session.cpp
  • test/tap/groups/groups.json
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
✅ Files skipped from review due to trivial changes (1)
  • lib/BaseHGC.cpp
🚧 Files skipped from review as they are similar to previous changes (6)
  • lib/MySQL_Session.cpp
  • lib/PgSQL_Session.cpp
  • test/tap/groups/groups.json
  • lib/MySQL_HostGroups_Manager.cpp
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names should use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)
Member variables should use snake_case
Constants and macros should use UPPER_SNAKE_CASE
Use C++17 features; conditional compilation should use #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, #ifdef PROXYSQLCLICKHOUSE (PROXYSQLGENAI no longer guards core code)
Use RAII for resource management and jemalloc for memory allocation
Use pthread mutexes for synchronization and std::atomic<> for counters

Files:

  • include/Base_HostGroups_Manager.h
  • lib/PgSQL_HostGroups_Manager.cpp
include/**/*.{h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

Include guards should use #ifndef _CLASS*_H format

Files:

  • include/Base_HostGroups_Manager.h
🔇 Additional comments (2)
include/Base_HostGroups_Manager.h (1)

314-314: LGTM!

lib/PgSQL_HostGroups_Manager.cpp (1)

3784-3786: LGTM!

Also applies to: 3805-3806

@burnison burnison force-pushed the hostgroup_attribute_timeouts branch from 218796c to 63c3ab7 Compare May 14, 2026 18:54

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp`:
- Around line 258-325: Multiple early returns after calling admin_exec leave DB
mutations (global_variables, pgsql_hostgroup_attributes, pgsql_query_rules) in
place and skip the intended restore block; ensure restoration always runs by
routing all exits through a single cleanup path. Implement a scope-guard/RAII or
a restore lambda (call it e.g. restore_runtime) that performs the existing
restore logic and ensure it is invoked in a destructor or explicitly before
every EXIT_FAILURE return (or replace early returns with goto/return to a single
cleanup label). Update code sections that call admin_exec, and the test helpers
run_success_case/run_kill_case, so any failure or test exit triggers the restore
function and guarantees the snapshot is restored.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 75e70ea7-b331-4d9f-b6a9-a5651ee55414

📥 Commits

Reviewing files that changed from the base of the PR and between 218796c and 63c3ab7.

📒 Files selected for processing (9)
  • include/Base_HostGroups_Manager.h
  • lib/BaseHGC.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • lib/MySQL_Session.cpp
  • lib/PgSQL_HostGroups_Manager.cpp
  • lib/PgSQL_Session.cpp
  • test/tap/groups/groups.json
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
✅ Files skipped from review due to trivial changes (2)
  • lib/BaseHGC.cpp
  • test/tap/groups/groups.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • include/Base_HostGroups_Manager.h
  • lib/PgSQL_HostGroups_Manager.cpp
  • lib/MySQL_Session.cpp
  • lib/MySQL_HostGroups_Manager.cpp
  • test/tap/tests/test_hostgroup_default_query_timeout-t.cpp
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names should use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)
Member variables should use snake_case
Constants and macros should use UPPER_SNAKE_CASE
Use C++17 features; conditional compilation should use #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, #ifdef PROXYSQLCLICKHOUSE (PROXYSQLGENAI no longer guards core code)
Use RAII for resource management and jemalloc for memory allocation
Use pthread mutexes for synchronization and std::atomic<> for counters

Files:

  • lib/PgSQL_Session.cpp
  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
test/tap/tests/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Test files should follow naming pattern test_*.cpp or *-t.cpp in test/tap/tests/

Files:

  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
🧠 Learnings (1)
📚 Learning: 2026-01-20T09:34:19.124Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:39-48
Timestamp: 2026-01-20T09:34:19.124Z
Learning: In ProxySQL's TAP test suite, resource leaks (e.g., not calling mysql_close() on early return paths) are commonly tolerated because test processes are short-lived and OS frees resources on exit. This pattern applies to all C++ test files under test/tap/tests. When reviewing, recognize this as a project-wide test convention and focus on test correctness and isolation rather than insisting on fixing such leaks in these test files.

Applied to files:

  • test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp
🔇 Additional comments (2)
lib/PgSQL_Session.cpp (2)

2767-2770: Please confirm this hostgroup timeout read is synchronized with admin reload writes.

This appears to be the same unresolved read-path concern already raised earlier; if attributes.default_query_timeout is still non-atomic/non-locked, this remains racy.


2771-2779: LGTM!

Comment thread test/tap/tests/pgsql-hostgroup_default_query_timeout-t.cpp Outdated
@burnison burnison force-pushed the hostgroup_attribute_timeouts branch 2 times, most recently from 7efc0dd to 8d264e5 Compare May 14, 2026 23:13
@burnison burnison force-pushed the hostgroup_attribute_timeouts branch from 8d264e5 to acb5742 Compare May 26, 2026 19:32
We have a use-case where we'd want to set query timeouts on a hostgroup
basis. This is currently only possible globally or by using query rules,
but I'd like to be able to handle this in constant-time and without
having to pin the rule to a specific user.

This change adds a `default_query_timeout` JSON pseudo-attribute in the
`mysql_hostgroup_attributes.hostgroup_settings` column, which will
override the global default, but will, itself, be overridden by a rule.

```
INSERT INTO mysql_hostgroup_attributes (hostgroup_id, hostgroup_settings)
VALUES (100, '{"default_query_timeout": 8000}');

LOAD MYSQL SERVERS TO RUNTIME;
```
@burnison burnison force-pushed the hostgroup_attribute_timeouts branch from acb5742 to 52ba60b Compare June 8, 2026 20:33
@sonarqubecloud

sonarqubecloud Bot commented Jun 8, 2026

Copy link
Copy Markdown

@renecannao

Copy link
Copy Markdown
Contributor

Hi @burnison ,

We will try to review this in time for 3.0.10 . Thank you for your patience

…roup_settings

init_myhgc_hostgroup_settings is defined in three translation units
(Base_HostGroups_Manager.cpp, MySQL_HostGroups_Manager.cpp, and
PgSQL_HostGroups_Manager.cpp), all archived into the same libproxysql.a.
PR sysown#5772 updated the MySQL and PgSQL copies to parse the new
'hostgroup_settings.default_query_timeout' field, but not the Base copy.

Because the Base copy also defines generate_mysql_hostgroup_attributes_table,
the linker could bind the Base (unchanged) variant depending on member
resolution order, causing the feature to silently fail to apply.

Mirror the parsing block and doc-comment update so all three copies agree,
making the feature linker-independent.
@sonarqubecloud

sonarqubecloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants