Skip to content

Add support for GTID Range#5557

Merged
renecannao merged 13 commits intov3.0from
feature/gtid-range-update
Apr 13, 2026
Merged

Add support for GTID Range#5557
renecannao merged 13 commits intov3.0from
feature/gtid-range-update

Conversation

@wazir-ahmed
Copy link
Copy Markdown
Member

@wazir-ahmed wazir-ahmed commented Apr 1, 2026

Summary by CodeRabbit

  • Refactor
    • GTID handling reworked as new object-oriented types and APIs; serialization and membership checks now use instance methods and legacy free-function helpers were removed.
  • Tests
    • Legacy GTID unit test replaced with focused suites covering interval behavior, set operations (add/merge/serialize/copy), and GTID protocol parsing and edge cases.

plisandro and others added 8 commits December 22, 2025 17:20
refactor: Extract GTID interval logic into `Gtid_Interval` class
This PR adds full support for ranges in `proxysql_mysqlbinlog` update messages, while
also improving efficiency when dealing with GTID gaps for any given UUID.

Single GTID updates are transparently supported, so older `proxysql_mysqlbinlog`
version will continue to work with newer ProxySQL releases.

See sysown/proxysql_mysqlbinlog#33 for details.
Signed-off-by: Wazir Ahmed <wazir@proxysql.com>
Signed-off-by: Wazir Ahmed <wazir@proxysql.com>
Signed-off-by: Wazir Ahmed <wazir@proxysql.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

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

Replaces legacy typedef-based GTID representations and free helper functions with class-based TrxId_Interval and GTID_Set; implements new GTID logic in proxysql_gtid.{h,cpp}; updates GTID_Server_Data, hostgroup headers/usage, build artifacts, and unit tests to use the new classes and APIs.

Changes

Cohort / File(s) Summary
GTID Core Types & Impl
include/proxysql_gtid.h, lib/proxysql_gtid.cpp
Introduce TrxId_Interval and GTID_Set classes (constructors, add/merge/append/contains, to_string); remove legacy typedefs (gtid_t, gtid_interval_t, gtid_set_t).
GTID Server Data
include/GTID_Server_Data.h, lib/GTID_Server_Data.cpp
Change gtid_executed member type to GTID_Set; delegate membership and updates to GTID_Set::has_gtid() / GTID_Set::add(); add parsing error handling that marks nodes inactive and stops IO on protocol errors; remove old GTID free helpers.
HostGroups Managers & Headers
include/Base_HostGroups_Manager.h, include/MySQL_HostGroups_Manager.h, lib/MySQL_HostGroups_Manager.cpp
Remove in-header free-function declarations and commented placeholders; reorder/includes and add GTID_Server_Data.h; switch serialization calls to gtid_executed.to_string().
Build
lib/Makefile
Add proxysql_gtid.oo to C++ object list so the new implementation is compiled/linked.
Tests & Test Config
test/tap/tests/unit/gtid_utils_unit-t.cpp (deleted), test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp, test/tap/tests/unit/gtid_set_unit-t.cpp, test/tap/tests/unit/gtid_server_data_unit-t.cpp, test/tap/tests/unit/Makefile, test/tap/groups/groups.json
Remove legacy GTID utils test; add unit tests for TrxId_Interval, GTID_Set, and GTID_Server_Data parsing; update unit test Makefile and test group mappings.
Public Header Cleanup
include/Base_HostGroups_Manager.h, include/MySQL_HostGroups_Manager.h
Drop direct dependency on old proxysql_gtid.h typedefs and free helpers; include GTID_Server_Data.h and tidy includes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Parser as GTID Parser
  participant GSD as GTID_Server_Data
  participant GSet as GTID_Set
  participant HGM as HostGroupsMgr

  Parser->>GSD: read_next_gtid(tokenized message)
  GSD->>GSet: gtid_executed.add(uuid, token)
  GSet-->>GSD: add result (bool)
  HGM->>GSD: query gtid_exists(uuid, trxid)
  GSD->>GSet: gtid_executed.has_gtid(uuid, trxid)
  GSet-->>HGM: membership bool
  HGM->>HGM: gtid_executed.to_string() for serialization
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I hopped through ranges, stitched each thread,
From lone ids to intervals neatly spread.
I nudged gaps close with gentle, careful paws,
Now GTID sets hum without old flaws.
Tests hop forward — a rabbit's applause. 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add support for GTID Range' directly aligns with the changeset's primary objective—refactoring GTID handling from legacy typedef-based representations to new class-based abstractions (TrxId_Interval and GTID_Set) that enable better range-based GTID operations.
Docstring Coverage ✅ Passed Docstring coverage is 80.77% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/gtid-range-update

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 and usage tips.

Copy link
Copy Markdown

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

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 refactors the GTID management system by introducing the TrxId_Interval and GTID_Set classes to replace the previous typedef-based implementation. These classes centralize logic for interval merging, membership validation, and serialization to the MySQL GTID format. The refactor includes updates to GTID_Server_Data and MySQL_HostGroups_Manager, the removal of legacy helper functions, and the addition of comprehensive unit tests. Review feedback highlights a potential null pointer dereference in GTID_Server_Data.cpp, portability concerns with sscanf format strings, and opportunities for optimization in the GTID_Set copy and add methods. A safety check for UUID string lengths was also recommended to prevent potential runtime exceptions during formatting.

Comment thread lib/GTID_Server_Data.cpp
Comment thread lib/proxysql_gtid.cpp
Comment thread lib/proxysql_gtid.cpp
Comment thread lib/proxysql_gtid.cpp
Comment thread lib/proxysql_gtid.cpp
Comment thread lib/proxysql_gtid.cpp
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
include/proxysql_gtid.h (1)

1-2: ⚠️ Potential issue | 🟡 Minor

Include guard format does not match repository rule.

#ifndef PROXYSQL_GTID / #define PROXYSQL_GTID does not follow the required include-guard pattern for headers under include/.

Suggested guard format
-#ifndef PROXYSQL_GTID
-#define PROXYSQL_GTID
+#ifndef __CLASS_PROXYSQL_GTID_H
+#define __CLASS_PROXYSQL_GTID_H
...
-#endif /* PROXYSQL_GTID */
+#endif /* __CLASS_PROXYSQL_GTID_H */

As per coding guidelines "include/**/.{h,hpp}: Include guards must follow the pattern #ifndef _CLASS_H".

Also applies to: 56-56

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@include/proxysql_gtid.h` around lines 1 - 2, The current include guard macros
PROXYSQL_GTID in proxysql_gtid.h don't follow the repo pattern; replace them
with the required format by changing `#ifndef` PROXYSQL_GTID and `#define`
PROXYSQL_GTID to `#ifndef` __CLASS_PROXYSQL_GTID_H and `#define`
__CLASS_PROXYSQL_GTID_H, and update the trailing `#endif` to include a comment
like /* __CLASS_PROXYSQL_GTID_H */ so the guard matches the "#ifndef
__CLASS_*_H" rule used for headers under include/.
🧹 Nitpick comments (3)
include/MySQL_HostGroups_Manager.h (1)

26-27: Minor: Redundant include.

GTID_Server_Data.h is already included via Base_HostGroups_Manager.h (line 26). The direct include on line 27 is redundant, though harmless due to include guards.

♻️ Suggested cleanup
 `#include` "proxysql.h"
 `#include` "cpp.h"
 `#include` "Base_HostGroups_Manager.h"
-#include "GTID_Server_Data.h"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@include/MySQL_HostGroups_Manager.h` around lines 26 - 27, Remove the
redundant direct include of GTID_Server_Data.h from the top of
include/MySQL_HostGroups_Manager.h since GTID_Server_Data.h is already pulled in
via Base_HostGroups_Manager.h; keep the Base_HostGroups_Manager.h include and
the MySQL_HostGroups_Manager declarations intact, and delete the extra `#include`
"GTID_Server_Data.h" line to avoid needless duplication while preserving include
guards.
lib/proxysql_gtid.cpp (1)

22-36: Potential portability issue with %ld format specifier.

trxid_t is int64_t, but sscanf with %ld assumes long which is only guaranteed to be 32-bit minimum. On 32-bit platforms or Windows, this could truncate values.

Consider using the portable format macro from <cinttypes>:

♻️ Portable format specifier
+#include <cinttypes>
+
 // Initializes a trxid interval from a C string buffer, in [trxid]{-[trxid]} format.
 TrxId_Interval::TrxId_Interval(const char *s) {
 	trxid_t _start = 0, _end = 0;

-	if (sscanf(s, "%ld-%ld", &_start, &_end) == 2) {
+	if (sscanf(s, "%" SCNd64 "-%" SCNd64, &_start, &_end) == 2) {
 		start = _start;
 		end = _end;
-	} else if (sscanf(s, "%ld", &_start) == 1) {
+	} else if (sscanf(s, "%" SCNd64, &_start) == 1) {
 		start = _start;
 		end = _start;
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/proxysql_gtid.cpp` around lines 22 - 36, TrxId_Interval::TrxId_Interval
uses sscanf with "%ld" but trxid_t is int64_t, causing truncation on some
platforms; fix by using the portable int64 scanf macro from <cinttypes> (SCNd64)
and update the sscanf format strings in TrxId_Interval::TrxId_Interval to use
"%" SCNd64 "-%" SCNd64 for the two-value parse and "%" SCNd64 for the
single-value parse, and add the <cinttypes> include if not present so sscanf
reads into trxid_t (_start, _end) correctly across platforms.
include/proxysql_gtid.h (1)

12-12: Rename classes to include the required protocol prefix.

TrxId_Interval and GTID_Set are PascalCase, but they miss the required MySQL_, PgSQL_, or ProxySQL_ prefix.

As per coding guidelines "Class names must use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)".

Also applies to: 36-36

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@include/proxysql_gtid.h` at line 12, The classes TrxId_Interval and GTID_Set
must be renamed to include the required protocol prefix; change TrxId_Interval
to ProxySQL_TrxId_Interval and GTID_Set to ProxySQL_GTID_Set, then update all
references (constructors, destructors, forward declarations, typedefs, method
signatures, use-sites, and any serialization/parsing helpers) to the new names
so compilation and linkage succeed; ensure header guards, comments, and any .cpp
usages are updated accordingly and run a full build to catch remaining
references.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/tap/tests/unit/gtid_set_unit-t.cpp`:
- Around line 14-17: The test source is missing the required test harness
headers; modify the includes in gtid_set_unit-t.cpp so that after the existing
`#include` "tap.h" you add `#include` "test_globals.h" and `#include` "test_init.h"
before the existing `#include` "proxysql_gtid.h" so the unit test links against
the custom harness and libproxysql.a (look for the include block at the top of
the file).

---

Outside diff comments:
In `@include/proxysql_gtid.h`:
- Around line 1-2: The current include guard macros PROXYSQL_GTID in
proxysql_gtid.h don't follow the repo pattern; replace them with the required
format by changing `#ifndef` PROXYSQL_GTID and `#define` PROXYSQL_GTID to `#ifndef`
__CLASS_PROXYSQL_GTID_H and `#define` __CLASS_PROXYSQL_GTID_H, and update the
trailing `#endif` to include a comment like /* __CLASS_PROXYSQL_GTID_H */ so the
guard matches the "#ifndef __CLASS_*_H" rule used for headers under include/.

---

Nitpick comments:
In `@include/MySQL_HostGroups_Manager.h`:
- Around line 26-27: Remove the redundant direct include of GTID_Server_Data.h
from the top of include/MySQL_HostGroups_Manager.h since GTID_Server_Data.h is
already pulled in via Base_HostGroups_Manager.h; keep the
Base_HostGroups_Manager.h include and the MySQL_HostGroups_Manager declarations
intact, and delete the extra `#include` "GTID_Server_Data.h" line to avoid
needless duplication while preserving include guards.

In `@include/proxysql_gtid.h`:
- Line 12: The classes TrxId_Interval and GTID_Set must be renamed to include
the required protocol prefix; change TrxId_Interval to ProxySQL_TrxId_Interval
and GTID_Set to ProxySQL_GTID_Set, then update all references (constructors,
destructors, forward declarations, typedefs, method signatures, use-sites, and
any serialization/parsing helpers) to the new names so compilation and linkage
succeed; ensure header guards, comments, and any .cpp usages are updated
accordingly and run a full build to catch remaining references.

In `@lib/proxysql_gtid.cpp`:
- Around line 22-36: TrxId_Interval::TrxId_Interval uses sscanf with "%ld" but
trxid_t is int64_t, causing truncation on some platforms; fix by using the
portable int64 scanf macro from <cinttypes> (SCNd64) and update the sscanf
format strings in TrxId_Interval::TrxId_Interval to use "%" SCNd64 "-%" SCNd64
for the two-value parse and "%" SCNd64 for the single-value parse, and add the
<cinttypes> include if not present so sscanf reads into trxid_t (_start, _end)
correctly across platforms.
🪄 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: 42b30b17-dfce-42b1-96d0-36b03a21f494

📥 Commits

Reviewing files that changed from the base of the PR and between d0625dc and 06b6343.

📒 Files selected for processing (13)
  • include/Base_HostGroups_Manager.h
  • include/GTID_Server_Data.h
  • include/MySQL_HostGroups_Manager.h
  • include/proxysql_gtid.h
  • lib/GTID_Server_Data.cpp
  • lib/Makefile
  • lib/MySQL_HostGroups_Manager.cpp
  • lib/proxysql_gtid.cpp
  • test/tap/groups/groups.json
  • test/tap/tests/unit/Makefile
  • test/tap/tests/unit/gtid_set_unit-t.cpp
  • test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp
  • test/tap/tests/unit/gtid_utils_unit-t.cpp
💤 Files with no reviewable changes (1)
  • test/tap/tests/unit/gtid_utils_unit-t.cpp
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: CI-builds / builds (ubuntu24,-tap-genai-gcov)
  • GitHub Check: CI-builds / builds (ubuntu22,-tap)
  • GitHub Check: CI-builds / builds (debian12,-dbg)
  • GitHub Check: run / trigger
  • GitHub Check: claude-review
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{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
Constants and macros must use UPPER_SNAKE_CASE
C++17 is required; use conditional compilation via #ifdef PROXYSQLGENAI, #ifdef PROXYSQL31, etc. for feature flags
Use pthread mutexes for synchronization and std::atomic<> for counters

Files:

  • include/Base_HostGroups_Manager.h
  • include/MySQL_HostGroups_Manager.h
  • lib/MySQL_HostGroups_Manager.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
  • include/GTID_Server_Data.h
  • test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp
  • lib/GTID_Server_Data.cpp
  • lib/proxysql_gtid.cpp
  • include/proxysql_gtid.h
include/**/*.{h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

Include guards must follow the pattern #ifndef _CLASS*_H

Files:

  • include/Base_HostGroups_Manager.h
  • include/MySQL_HostGroups_Manager.h
  • include/GTID_Server_Data.h
  • include/proxysql_gtid.h
**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Use RAII for resource management and jemalloc for memory allocation

Files:

  • lib/MySQL_HostGroups_Manager.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
  • test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp
  • lib/GTID_Server_Data.cpp
  • lib/proxysql_gtid.cpp
lib/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

One class per file is the typical convention

Files:

  • lib/MySQL_HostGroups_Manager.cpp
  • lib/GTID_Server_Data.cpp
  • lib/proxysql_gtid.cpp
test/tap/tests/unit/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h and link against libproxysql.a via the custom test harness

Files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
  • test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp
🧠 Learnings (10)
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to **/*.{cpp,h,hpp} : C++17 is required; use conditional compilation via `#ifdef` PROXYSQLGENAI, `#ifdef` PROXYSQL31, etc. for feature flags

Applied to files:

  • lib/Makefile
  • include/Base_HostGroups_Manager.h
  • include/MySQL_HostGroups_Manager.h
  • include/GTID_Server_Data.h
  • lib/proxysql_gtid.cpp
  • include/proxysql_gtid.h
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to test/tap/tests/unit/**/*.cpp : Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h and link against libproxysql.a via the custom test harness

Applied to files:

  • lib/Makefile
  • test/tap/tests/unit/Makefile
  • test/tap/groups/groups.json
  • include/Base_HostGroups_Manager.h
  • include/MySQL_HostGroups_Manager.h
  • test/tap/tests/unit/gtid_set_unit-t.cpp
  • test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp
  • lib/proxysql_gtid.cpp
📚 Learning: 2026-01-20T09:34:27.165Z
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:27.165Z
Learning: In ProxySQL test files (test/tap/tests/), resource leaks (such as not calling `mysql_close()` on early return paths) are not typically fixed because test processes are short-lived and the OS frees resources on process exit. This is a common pattern across the test suite.

Applied to files:

  • lib/Makefile
  • include/MySQL_HostGroups_Manager.h
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to **/*.{cpp,h,hpp} : Class names must use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)

Applied to files:

  • lib/Makefile
  • include/Base_HostGroups_Manager.h
  • include/MySQL_HostGroups_Manager.h
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Admin interface uses SQLite3 backend for SQL-based configuration and schema versions are tracked in ProxySQL_Admin_Tables_Definitions.h

Applied to files:

  • lib/Makefile
  • include/MySQL_HostGroups_Manager.h
📚 Learning: 2026-01-20T07:40:34.938Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:24-28
Timestamp: 2026-01-20T07:40:34.938Z
Learning: In ProxySQL test files, calling `mysql_error(NULL)` after `mysql_init()` failure is safe because the MariaDB client library implementation returns an empty string for NULL handles (not undefined behavior).

Applied to files:

  • lib/Makefile
  • include/Base_HostGroups_Manager.h
  • include/MySQL_HostGroups_Manager.h
📚 Learning: 2026-02-13T05:55:42.693Z
Learnt from: mevishalr
Repo: sysown/proxysql PR: 5364
File: lib/MySQL_Logger.cpp:1211-1232
Timestamp: 2026-02-13T05:55:42.693Z
Learning: In ProxySQL, the MySQL_Logger and PgSQL_Logger destructors run after all worker threads have been joined during shutdown. The sequence in src/main.cpp is: (1) join all worker threads, (2) call ProxySQL_Main_shutdown_all_modules() which deletes the loggers. Therefore, there is no concurrent thread access during logger destruction, and lock ordering in the destructors cannot cause deadlocks.

Applied to files:

  • include/Base_HostGroups_Manager.h
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Feature tiers are controlled by build flags: PROXYSQL31=1 for v3.1.x, PROXYSQLGENAI=1 for v4.0.x; PROXYSQLGENAI=1 implies PROXYSQL31=1

Applied to files:

  • include/MySQL_HostGroups_Manager.h
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to test/tap/tests/{test_*,*-t}.cpp : Test files in test/tap/tests/ must follow the naming pattern test_*.cpp or *-t.cpp

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
  • test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp
📚 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/unit/gtid_set_unit-t.cpp
  • test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp
🔇 Additional comments (16)
lib/Makefile (1)

100-100: GTID object inclusion is correctly wired into the static library build.

Adding proxysql_gtid.oo to _OBJ_CXX ensures the new GTID implementation is compiled and packaged into libproxysql.a for downstream linkage.

test/tap/tests/unit/Makefile (1)

288-289: New GTID unit tests are correctly registered in the unit-test suite.

Both targets are added to UNIT_TESTS, so they are built via the existing pattern rule and executed through the normal all flow.

lib/MySQL_HostGroups_Manager.cpp (1)

5554-5555: GTID string serialization update looks correct.

Using GTID_Set::to_string() here is consistent with the new class-based GTID model and keeps the existing result-row behavior intact.

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

372-374: LGTM!

The test group configuration correctly replaces the removed gtid_utils_unit-t with the two new GTID unit test binaries, properly mapping them to the unit-tests-g1 group.

include/GTID_Server_Data.h (1)

6-6: LGTM!

The header correctly transitions from the legacy gtid_set_t typedef to the new GTID_Set class abstraction. The include for proxysql_gtid.h provides the necessary type definition.

Also applies to: 20-20

include/Base_HostGroups_Manager.h (1)

21-22: LGTM!

The include change correctly switches from direct proxysql_gtid.h inclusion to GTID_Server_Data.h, which provides the necessary GTID types transitively. The removal of free-function declarations (gtid_executed_to_string, addGtid) aligns with the migration to GTID_Set methods.

test/tap/tests/unit/gtid_set_unit-t.cpp (1)

291-312: LGTM! Comprehensive test coverage.

The test suite provides thorough coverage of GTID_Set operations including interval addition, membership checks, serialization, clearing, and deep copying. The assertion count (62) is properly documented with per-function breakdowns.

lib/GTID_Server_Data.cpp (4)

263-265: LGTM!

Clean delegation to the new GTID_Set::has_gtid() method, replacing the previous manual iteration logic.


302-308: Good documentation.

The wire format comment clearly documents the three message types (ST=, I1=, I2=) and their formats, aiding future maintainability.


353-355: LGTM!

The bootstrap parsing now correctly uses GTID_Set::add(uuid, subtoken) which handles both single trxid and range formats internally via TrxId_Interval(const char*) constructor.


377-381: LGTM!

The I1/I2 message parsing correctly uses GTID_Set::add() with the string token, which internally constructs a TrxId_Interval from the parsed format.

test/tap/tests/unit/gtid_trxid_interval_unit-t.cpp (1)

1-202: LGTM! Well-structured test coverage.

The test suite comprehensively covers TrxId_Interval operations:

  • All constructor variants (range, single, string literal, std::string, negative values)
  • Membership checks (contains for both trxid and interval)
  • Serialization (to_string)
  • Mutation operations (append, merge) with proper acceptance/rejection cases
  • Comparison operators

The 48 planned assertions are well-documented with per-function breakdowns.

lib/proxysql_gtid.cpp (2)

148-193: LGTM! Well-implemented interval merge logic.

The add() implementation correctly handles:

  1. Fast-path append for sequential additions
  2. Containment check to avoid duplicates
  3. Merge with existing intervals
  4. Post-merge consolidation via sort + merge pass

The algorithm maintains a sorted, non-overlapping interval list efficiently.


231-248: LGTM!

The to_string() implementation correctly formats the 32-character UUID string into the standard 8-4-4-4-12 hyphenated format by inserting hyphens at the appropriate positions.

include/proxysql_gtid.h (2)

46-50: add(...) overload set is clean and practical.

The overloads for interval/trxid/string inputs give a clear and ergonomic API surface for callers.


23-33: Apply proper const-qualification to method signatures in TrxId_Interval and GTID_Set classes.

Return-type const qualifiers are redundant for value returns; query and comparison methods should be marked const instead.

Proposed signature cleanup
-		const bool contains(const TrxId_Interval& other);
-		const bool contains(trxid_t trxid);
-		const std::string to_string(void);
-		const bool append(const TrxId_Interval& other);
-		const bool merge(const TrxId_Interval& other);
+		bool contains(const TrxId_Interval& other) const;
+		bool contains(trxid_t trxid) const;
+		std::string to_string() const;
+		bool append(const TrxId_Interval& other);
+		bool merge(const TrxId_Interval& other);

-		const int cmp(const TrxId_Interval& other);
-		const bool operator<(const TrxId_Interval& other);
-		const bool operator==(const TrxId_Interval& other);
-		const bool operator!=(const TrxId_Interval& other);
+		int cmp(const TrxId_Interval& other) const;
+		bool operator<(const TrxId_Interval& other) const;
+		bool operator==(const TrxId_Interval& other) const;
+		bool operator!=(const TrxId_Interval& other) const;

-		GTID_Set copy();
+		GTID_Set copy() const;

-		const bool has_gtid(const std::string& uuid, const trxid_t trxid);
-		const std::string to_string(void);
+		bool has_gtid(const std::string& uuid, trxid_t trxid) const;
+		std::string to_string() const;

Also applies to: lines 43, 52–53

Comment thread test/tap/tests/unit/gtid_set_unit-t.cpp
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/proxysql_gtid.cpp`:
- Around line 150-155: The fast-path in GTID_Set::add() returns true when
it->second.back().append(iv) succeeds even if the tail interval's end didn't
actually change; capture the tail interval's current end before calling
it->second.back().append(iv), call append(iv), then compare the previous end to
the new end and only return true if the end changed (otherwise treat as no-op
and let the later containment check run). Update the code around
it->second.back().append(iv) to perform this pre/post-end comparison so
duplicates like [10,20], [15,20], or 20 are not reported as mutations.
- Around line 61-64: The comparisons in TrxId_Interval::append and
TrxId_Interval::merge use end+1 and start-1 which can overflow trxid_t at
int64_t limits; fix by guarding those adjacency checks: instead of computing
end+1 or start-1 unconditionally, first test if end == INT64_MAX (for end+1) or
start == INT64_MIN (for start-1) and handle those edge cases (treat as
non-adjacent or use adjusted logic), or rewrite the condition as a safe range
comparison (e.g., check other.start <= end or (end < INT64_MAX && other.start ==
end + 1)); apply the same pattern for other.end/start in merge so no signed
overflow occurs when evaluating (end+1) or (start-1).
- Around line 22-35: The TrxId_Interval constructor can leave start/end
uninitialized and dereference a null s; change
TrxId_Interval::TrxId_Interval(const char*) to validate the input string (check
s!=nullptr), initialize start and end to a safe sentinel (or set a boolean valid
flag) before parsing, and only accept the parsed interval when sscanf returns a
success (otherwise mark the interval invalid or throw); update GTID_Set::add
overloads that forward strings into TrxId_Interval to detect and propagate
parsing failure instead of creating an indeterminate object. Also fix
TrxId_Interval::append adjacency logic to avoid overflow by checking end !=
INT64_MAX before computing end+1 (treat INT64_MAX as non-adjacent or handle
specially). Ensure all callers check the interval’s validity flag or handle
exceptions accordingly.
🪄 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: f090b7ba-b1d1-4a1e-b345-56a22ec20d7e

📥 Commits

Reviewing files that changed from the base of the PR and between 06b6343 and 7ae0add.

📒 Files selected for processing (2)
  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: CI-builds / builds (ubuntu22,-tap)
  • GitHub Check: CI-builds / builds (debian12,-dbg)
  • GitHub Check: CI-builds / builds (ubuntu24,-tap-genai-gcov)
  • GitHub Check: run / trigger
  • GitHub Check: claude-review
🧰 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
Constants and macros must use UPPER_SNAKE_CASE
C++17 is required; use conditional compilation via #ifdef PROXYSQLGENAI, #ifdef PROXYSQL31, etc. for feature flags
Use pthread mutexes for synchronization and std::atomic<> for counters

Files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Use RAII for resource management and jemalloc for memory allocation

Files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
lib/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

One class per file is the typical convention

Files:

  • lib/proxysql_gtid.cpp
test/tap/tests/unit/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h and link against libproxysql.a via the custom test harness

Files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
🧠 Learnings (8)
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to **/*.{cpp,h,hpp} : C++17 is required; use conditional compilation via `#ifdef` PROXYSQLGENAI, `#ifdef` PROXYSQL31, etc. for feature flags

Applied to files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-04-01T21:27:00.297Z
Learnt from: wazir-ahmed
Repo: sysown/proxysql PR: 5557
File: test/tap/tests/unit/gtid_set_unit-t.cpp:14-17
Timestamp: 2026-04-01T21:27:00.297Z
Learning: In ProxySQL unit tests under test/tap/tests/unit/, include test_globals.h and test_init.h only for tests that depend on ProxySQL runtime globals/initialization (i.e., tests that exercise components linked against libproxysql.a). For “pure” data-structure/utility tests (e.g., ezoption_parser_unit-t.cpp, gtid_set_unit-t.cpp, gtid_trxid_interval_unit-t.cpp) that do not require runtime globals/initialization, it is correct to omit test_globals.h and test_init.h and instead include only tap.h plus the relevant project header(s).

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to test/tap/tests/unit/**/*.cpp : Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h and link against libproxysql.a via the custom test harness

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to test/tap/tests/{test_*,*-t}.cpp : Test files in test/tap/tests/ must follow the naming pattern test_*.cpp or *-t.cpp

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 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/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to **/*.{cpp,h,hpp} : Class names must use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-03-26T16:39:02.446Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5548
File: lib/mysql_connection.cpp:1837-1843
Timestamp: 2026-03-26T16:39:02.446Z
Learning: In ProxySQL's lib/mysql_connection.cpp, `SHOW WARNINGS` detection for both `update_warning_count_from_connection()` and the `add_eof()` call in `ASYNC_USE_RESULT_CONT` intentionally uses `myds->sess->CurrentQuery.QueryParserArgs.digest_text` (comment-stripped digest text). This means the fix/feature does not work when `mysql-query_digests_keep_comment=1` (digest_text contains comments) or `mysql-query_digests=0` (digest_text is unavailable) — these configurations are explicitly excluded from the regression test for `reg_test_5306-show_warnings_with_comment-t`. This design is consistent across the codebase and is an accepted, documented limitation.

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-01-20T07:40:34.938Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:24-28
Timestamp: 2026-01-20T07:40:34.938Z
Learning: In ProxySQL test files, calling `mysql_error(NULL)` after `mysql_init()` failure is safe because the MariaDB client library implementation returns an empty string for NULL handles (not undefined behavior).

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
🪛 Clang (14.0.6)
lib/proxysql_gtid.cpp

[error] 1-1: 'cstdio' file not found

(clang-diagnostic-error)

test/tap/tests/unit/gtid_set_unit-t.cpp

[error] 14-14: 'tap.h' file not found

(clang-diagnostic-error)

Comment thread lib/proxysql_gtid.cpp
Comment thread lib/proxysql_gtid.cpp
Comment thread lib/proxysql_gtid.cpp
- Use MySQL GTID set formatting in `GTID_Set::to_string()`
- Initialize `TrxId_Interval` safely on null or invalid C-string input
- Return false for no-op tail additions in `GTID_Set::add()`
- Simplify `GTID_Set::copy()``

Signed-off-by: Wazir Ahmed <wazir@proxysql.com>
@wazir-ahmed wazir-ahmed force-pushed the feature/gtid-range-update branch from 7ae0add to a95acd0 Compare April 2, 2026 10:24
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

22-38: ⚠️ Potential issue | 🟠 Major

Reject malformed text ranges instead of coercing them into real intervals.

Bad input is still turned into GTID data here (nullptr/"foo" => [0,0], "10-" => [10,10]), and the string GTID_Set::add() overloads then persist it as a successful mutation. That silently corrupts the set and can later serialize invalid output like :0; parse failure needs to remain invalid all the way up the API.

Also applies to: 46-47, 209-216

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/proxysql_gtid.cpp` around lines 22 - 38, The TrxId_Interval constructor
currently coerces malformed input into [0,0] or partial intervals; change
TrxId_Interval::TrxId_Interval(const char *s) to treat parse failures as invalid
by (a) requiring sscanf to match the full expected format and not accepting
partial matches or nullptr, and (b) signaling failure (e.g. set a new boolean
member like valid = false or throw std::invalid_argument) instead of leaving
start/end as 0; then update callers—particularly GTID_Set::add() overloads—to
check that the TrxId_Interval is valid before persisting the interval and
reject/propagate the parse error so malformed strings never become stored GTID
entries.
🧹 Nitpick comments (1)
test/tap/tests/unit/gtid_set_unit-t.cpp (1)

56-65: Add a malformed-text regression next to the happy-path string tests.

These cases only validate valid ranges, so they will not catch junk input being materialized as a real interval. One negative assertion here would lock down the intended false/no-mutation behavior once the parser is fixed.

🧪 Suggested regression
 static void test_add_cstring_range() {
 	GTID_Set gs;
 
 	ok(gs.add(UUID_A, "9-22"), "add C string range: new range");
 	ok(gs.add(UUID_B, "31-50"), "add C string range: new range for UUID B");
+	ok(!gs.add(UUID_A, "foo"), "add C string range: malformed input returns false");
+	ok(gs.map[UUID_A].size() == 1, "add C string range: malformed input does not create a new interval");
 	ok(gs.map.size() == 2, "add C string range: two UUIDs");
 	auto it_a = gs.map[UUID_A].begin();

Also bump plan(62) to plan(64).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/tap/tests/unit/gtid_set_unit-t.cpp` around lines 56 - 65, Add a negative
regression to test_add_cstring_range that asserts GTID_Set::add returns false
and does not create a map entry when given a malformed C-string (e.g., junk or
invalid range format) so malformed input is rejected; update the test's plan
count from plan(62) to plan(64) accordingly. Locate the test_add_cstring_range
function and add one ok(...) asserting add(UUID_A, "bad-input") == false (or
that gs.map size remains unchanged / no new interval for UUID_A), and increment
the overall plan() call to 64.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@lib/proxysql_gtid.cpp`:
- Around line 22-38: The TrxId_Interval constructor currently coerces malformed
input into [0,0] or partial intervals; change
TrxId_Interval::TrxId_Interval(const char *s) to treat parse failures as invalid
by (a) requiring sscanf to match the full expected format and not accepting
partial matches or nullptr, and (b) signaling failure (e.g. set a new boolean
member like valid = false or throw std::invalid_argument) instead of leaving
start/end as 0; then update callers—particularly GTID_Set::add() overloads—to
check that the TrxId_Interval is valid before persisting the interval and
reject/propagate the parse error so malformed strings never become stored GTID
entries.

---

Nitpick comments:
In `@test/tap/tests/unit/gtid_set_unit-t.cpp`:
- Around line 56-65: Add a negative regression to test_add_cstring_range that
asserts GTID_Set::add returns false and does not create a map entry when given a
malformed C-string (e.g., junk or invalid range format) so malformed input is
rejected; update the test's plan count from plan(62) to plan(64) accordingly.
Locate the test_add_cstring_range function and add one ok(...) asserting
add(UUID_A, "bad-input") == false (or that gs.map size remains unchanged / no
new interval for UUID_A), and increment the overall plan() call to 64.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f7d82495-2ec7-40ae-a032-e1327a23ddba

📥 Commits

Reviewing files that changed from the base of the PR and between 7ae0add and a95acd0.

📒 Files selected for processing (2)
  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: CI-builds / builds (ubuntu22,-tap)
  • GitHub Check: CI-builds / builds (ubuntu24,-tap-genai-gcov)
  • GitHub Check: CI-builds / builds (debian12,-dbg)
  • GitHub Check: run / trigger
  • GitHub Check: claude-review
🧰 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
Constants and macros must use UPPER_SNAKE_CASE
C++17 is required; use conditional compilation via #ifdef PROXYSQLGENAI, #ifdef PROXYSQL31, etc. for feature flags
Use pthread mutexes for synchronization and std::atomic<> for counters

Files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Use RAII for resource management and jemalloc for memory allocation

Files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
lib/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

One class per file is the typical convention

Files:

  • lib/proxysql_gtid.cpp
test/tap/tests/unit/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h and link against libproxysql.a via the custom test harness

Files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
🧠 Learnings (10)
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to **/*.{cpp,h,hpp} : C++17 is required; use conditional compilation via `#ifdef` PROXYSQLGENAI, `#ifdef` PROXYSQL31, etc. for feature flags

Applied to files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-04-01T21:27:00.297Z
Learnt from: wazir-ahmed
Repo: sysown/proxysql PR: 5557
File: test/tap/tests/unit/gtid_set_unit-t.cpp:14-17
Timestamp: 2026-04-01T21:27:00.297Z
Learning: In ProxySQL's unit test directory (test/tap/tests/unit/), test_globals.h and test_init.h are only required for tests that depend on the ProxySQL runtime globals/initialization (i.e., tests that exercise components linked against libproxysql.a). Pure data-structure or utility tests (e.g., ezoption_parser_unit-t.cpp, gtid_set_unit-t.cpp, gtid_trxid_interval_unit-t.cpp) only need tap.h and the relevant project header — omitting test_globals.h and test_init.h is correct and intentional in these cases.

Applied to files:

  • lib/proxysql_gtid.cpp
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to test/tap/tests/unit/**/*.cpp : Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h and link against libproxysql.a via the custom test harness

Applied to files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-03-26T16:39:02.446Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5548
File: lib/mysql_connection.cpp:1837-1843
Timestamp: 2026-03-26T16:39:02.446Z
Learning: In ProxySQL's lib/mysql_connection.cpp, `SHOW WARNINGS` detection for both `update_warning_count_from_connection()` and the `add_eof()` call in `ASYNC_USE_RESULT_CONT` intentionally uses `myds->sess->CurrentQuery.QueryParserArgs.digest_text` (comment-stripped digest text). This means the fix/feature does not work when `mysql-query_digests_keep_comment=1` (digest_text contains comments) or `mysql-query_digests=0` (digest_text is unavailable) — these configurations are explicitly excluded from the regression test for `reg_test_5306-show_warnings_with_comment-t`. This design is consistent across the codebase and is an accepted, documented limitation.

Applied to files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-01-20T07:40:34.938Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:24-28
Timestamp: 2026-01-20T07:40:34.938Z
Learning: In ProxySQL test files, calling `mysql_error(NULL)` after `mysql_init()` failure is safe because the MariaDB client library implementation returns an empty string for NULL handles (not undefined behavior).

Applied to files:

  • lib/proxysql_gtid.cpp
  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-01-20T09:34:27.165Z
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:27.165Z
Learning: In ProxySQL test files (test/tap/tests/), resource leaks (such as not calling `mysql_close()` on early return paths) are not typically fixed because test processes are short-lived and the OS frees resources on process exit. This is a common pattern across the test suite.

Applied to files:

  • lib/proxysql_gtid.cpp
📚 Learning: 2026-04-01T21:27:00.297Z
Learnt from: wazir-ahmed
Repo: sysown/proxysql PR: 5557
File: test/tap/tests/unit/gtid_set_unit-t.cpp:14-17
Timestamp: 2026-04-01T21:27:00.297Z
Learning: In ProxySQL unit tests under test/tap/tests/unit/, include test_globals.h and test_init.h only for tests that depend on ProxySQL runtime globals/initialization (i.e., tests that exercise components linked against libproxysql.a). For “pure” data-structure/utility tests (e.g., ezoption_parser_unit-t.cpp, gtid_set_unit-t.cpp, gtid_trxid_interval_unit-t.cpp) that do not require runtime globals/initialization, it is correct to omit test_globals.h and test_init.h and instead include only tap.h plus the relevant project header(s).

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to test/tap/tests/{test_*,*-t}.cpp : Test files in test/tap/tests/ must follow the naming pattern test_*.cpp or *-t.cpp

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
📚 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/unit/gtid_set_unit-t.cpp
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to **/*.{cpp,h,hpp} : Class names must use PascalCase with protocol prefixes (MySQL_, PgSQL_, ProxySQL_)

Applied to files:

  • test/tap/tests/unit/gtid_set_unit-t.cpp
🪛 Clang (14.0.6)
lib/proxysql_gtid.cpp

[error] 1-1: 'cstdio' file not found

(clang-diagnostic-error)

test/tap/tests/unit/gtid_set_unit-t.cpp

[error] 14-14: 'tap.h' file not found

(clang-diagnostic-error)

… message

I1/I2 now strictly handle single trxid values (parsed via atoll).
New I3/I4 messages handle range-based trxid updates (parsed as
TrxId_Interval strings). This ensures backwards compatibility:
an old ProxySQL receiving I3/I4 will safely ignore them via
default:break, while a new ProxySQL correctly distinguishes
single vs range messages.

Also fixes events_read being incremented for unrecognized message
types, and disconnects on unknown message types instead of silently
ignoring them.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/GTID_Server_Data.cpp`:
- Line 318: The parser currently accepts an I4 interval and reuses uuid_server
even when no prior I1/I3 established that UUID; modify the handling in the
function that processes I4 (e.g., the method handling "I4" tokens or function
parseI4/appendInterval in GTID_Server_Data.cpp) to first check a boolean/state
set by processing I1/I3 (e.g., have_seen_I1_or_I3 or reuse_uuid_initialized) and
reject/return an error if that flag is not set; do not rely on uuid_server being
populated from ST= parsing alone, and ensure the same guard is applied to the
related code paths referenced around lines 403-405 so the code fails closed when
the first post-bootstrap range is I4.
- Line 273: GTID UUID strings must be canonicalized the same way before being
stored and looked up; update places that call gtid_executed.add(...) and
gtid_executed.has_gtid(...) (and the gtid_exists() path) to normalize the UUID
argument (e.g., remove hyphens and normalize case to match the ST= bootstrap
canonical form used by GTID_Set) before passing it to add() or has_gtid(); apply
the same normalization in both the call at the shown return line using
gtid_executed.has_gtid((std::string)gtid_uuid, gtid_trxid) and the other
affected block (around lines 388-401) so the GTID_Set lookups are consistent.
- Around line 395-411: In the '3' case handling I3 frames (in
GTID_Server_Data.cpp) guard against strchr returning nullptr: after a =
strchr(rec_msg+3, ':') check if a is NULL before computing ul or accessing a+1;
if NULL, call proxy_warning (matching the default error message with rec_msg[1],
port, address, mysql_port), set active = false and return false to avoid
UB/crash. Only when a is non-NULL compute ul, strncpy into uuid_server,
null-terminate, then call gtid_executed.add((std::string)uuid_server, a+1) and
increment events_read; similarly keep existing case '4' behavior unchanged.
🪄 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: e92424c8-a750-4caf-9973-ad47e0ee9849

📥 Commits

Reviewing files that changed from the base of the PR and between a95acd0 and dca01d4.

📒 Files selected for processing (1)
  • lib/GTID_Server_Data.cpp
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: CI-builds / builds (ubuntu22,-tap)
  • GitHub Check: CI-builds / builds (debian12,-dbg)
  • GitHub Check: CI-builds / builds (ubuntu24,-tap-genai-gcov)
  • GitHub Check: run / trigger
  • GitHub Check: claude-review
🧰 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
Constants and macros must use UPPER_SNAKE_CASE
C++17 is required; use conditional compilation via #ifdef PROXYSQLGENAI, #ifdef PROXYSQL31, etc. for feature flags
Use pthread mutexes for synchronization and std::atomic<> for counters

Files:

  • lib/GTID_Server_Data.cpp
**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Use RAII for resource management and jemalloc for memory allocation

Files:

  • lib/GTID_Server_Data.cpp
lib/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

One class per file is the typical convention

Files:

  • lib/GTID_Server_Data.cpp
🪛 Cppcheck (2.20.0)
lib/GTID_Server_Data.cpp

[warning] 86-86: If memory allocation fails, then there is a possible null pointer dereference

(nullPointerOutOfMemory)

🔇 Additional comments (1)
lib/GTID_Server_Data.cpp (1)

84-92: Fail-closed disconnect after parser deactivation looks good.

Cleaning up the watcher as soon as dump() marks the stream inactive keeps the reader from continuing on a protocol-bad socket.

Comment thread lib/GTID_Server_Data.cpp
Comment thread lib/GTID_Server_Data.cpp
Comment thread lib/GTID_Server_Data.cpp Outdated
Tests read_next_gtid() by buffer-stuffing, covering:
- ST= bootstrap with single trxids and ranges
- I1/I2 single trxid messages
- I3/I4 range-based messages
- I1 rejects range input (atoll parses only first number)
- Unknown message type sets active=false and returns false
- read_all_gtids() stops processing on unknown message
- Empty buffer and incomplete message edge cases
- Mixed message sequence with full GTID state verification
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/tap/tests/unit/gtid_server_data_unit-t.cpp (1)

32-40: Make buffer helper explicitly control cached UUID reset

stuff_buffer() replaces wire bytes but leaves uuid_server untouched. Because I2/I4 parsing consumes cached UUID state, this creates hidden coupling unless each call site is intentional. Consider making UUID reset explicit in the helper API and opt-out only where reuse is required.

Suggested refactor
-static void stuff_buffer(GTID_Server_Data &sd, const std::string &msg) {
+static void stuff_buffer(GTID_Server_Data &sd, const std::string &msg, bool reset_uuid = true) {
 	size_t needed = msg.size();
 	if (needed > sd.size) {
 		sd.resize(needed);
 	}
 	memcpy(sd.data, msg.c_str(), needed);
 	sd.len = needed;
 	sd.pos = 0;
+	if (reset_uuid) {
+		memset(sd.uuid_server, 0, sizeof(sd.uuid_server));
+	}
 }
-	stuff_buffer(sd, msg2);
+	stuff_buffer(sd, msg2, false); // I2 reuses UUID from previous I1
-	stuff_buffer(sd, msg2);
+	stuff_buffer(sd, msg2, false); // I4 reuses UUID from previous I3
-	stuff_buffer(sd, m2);
+	stuff_buffer(sd, m2, false); // I2 reuses UUID_A
...
-	stuff_buffer(sd, m4);
+	stuff_buffer(sd, m4, false); // I4 reuses UUID_B
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/tap/tests/unit/gtid_server_data_unit-t.cpp` around lines 32 - 40, The
helper stuff_buffer currently writes new wire bytes into GTID_Server_Data but
leaves the cached UUID state (uuid_server/have_uuid) intact, causing hidden
coupling; change stuff_buffer to explicitly control clearing the cached UUID by
adding a boolean parameter (e.g., bool reset_uuid = true) and, when true, clear
or invalidate the cached UUID fields on sd (reset sd.uuid_server and/or set
sd.have_uuid = false) before writing the buffer; keep an opt-out (false) for
callers that intentionally reuse the cached UUID and update call sites
accordingly to pass false only where reuse is required.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/tap/tests/unit/gtid_server_data_unit-t.cpp`:
- Around line 32-40: The helper stuff_buffer currently writes new wire bytes
into GTID_Server_Data but leaves the cached UUID state (uuid_server/have_uuid)
intact, causing hidden coupling; change stuff_buffer to explicitly control
clearing the cached UUID by adding a boolean parameter (e.g., bool reset_uuid =
true) and, when true, clear or invalidate the cached UUID fields on sd (reset
sd.uuid_server and/or set sd.have_uuid = false) before writing the buffer; keep
an opt-out (false) for callers that intentionally reuse the cached UUID and
update call sites accordingly to pass false only where reuse is required.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 929c2ca2-7362-45a3-937a-993c42b140bd

📥 Commits

Reviewing files that changed from the base of the PR and between dca01d4 and 307d70a.

📒 Files selected for processing (3)
  • test/tap/groups/groups.json
  • test/tap/tests/unit/Makefile
  • test/tap/tests/unit/gtid_server_data_unit-t.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/tap/tests/unit/Makefile
  • test/tap/groups/groups.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: CI-builds / builds (ubuntu22,-tap)
  • GitHub Check: CI-builds / builds (ubuntu24,-tap-genai-gcov)
  • GitHub Check: CI-builds / builds (debian12,-dbg)
  • GitHub Check: run / trigger
  • GitHub Check: claude-review
🧰 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
Constants and macros must use UPPER_SNAKE_CASE
C++17 is required; use conditional compilation via #ifdef PROXYSQLGENAI, #ifdef PROXYSQL31, etc. for feature flags
Use pthread mutexes for synchronization and std::atomic<> for counters

Files:

  • test/tap/tests/unit/gtid_server_data_unit-t.cpp
**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Use RAII for resource management and jemalloc for memory allocation

Files:

  • test/tap/tests/unit/gtid_server_data_unit-t.cpp
test/tap/tests/unit/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h and link against libproxysql.a via the custom test harness

Files:

  • test/tap/tests/unit/gtid_server_data_unit-t.cpp
🧠 Learnings (4)
📚 Learning: 2026-04-01T21:27:00.297Z
Learnt from: wazir-ahmed
Repo: sysown/proxysql PR: 5557
File: test/tap/tests/unit/gtid_set_unit-t.cpp:14-17
Timestamp: 2026-04-01T21:27:00.297Z
Learning: In ProxySQL unit tests under test/tap/tests/unit/, include test_globals.h and test_init.h only for tests that depend on ProxySQL runtime globals/initialization (i.e., tests that exercise components linked against libproxysql.a). For “pure” data-structure/utility tests (e.g., ezoption_parser_unit-t.cpp, gtid_set_unit-t.cpp, gtid_trxid_interval_unit-t.cpp) that do not require runtime globals/initialization, it is correct to omit test_globals.h and test_init.h and instead include only tap.h plus the relevant project header(s).

Applied to files:

  • test/tap/tests/unit/gtid_server_data_unit-t.cpp
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to test/tap/tests/unit/**/*.cpp : Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h and link against libproxysql.a via the custom test harness

Applied to files:

  • test/tap/tests/unit/gtid_server_data_unit-t.cpp
📚 Learning: 2026-03-22T14:38:16.093Z
Learnt from: CR
Repo: sysown/proxysql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:38:16.093Z
Learning: Applies to test/tap/tests/{test_*,*-t}.cpp : Test files in test/tap/tests/ must follow the naming pattern test_*.cpp or *-t.cpp

Applied to files:

  • test/tap/tests/unit/gtid_server_data_unit-t.cpp
📚 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/unit/gtid_server_data_unit-t.cpp
🪛 Clang (14.0.6)
test/tap/tests/unit/gtid_server_data_unit-t.cpp

[error] 14-14: 'tap.h' file not found

(clang-diagnostic-error)

🔇 Additional comments (2)
test/tap/tests/unit/gtid_server_data_unit-t.cpp (2)

45-287: Coverage quality is strong for protocol/state transitions

Nice work covering success paths, UUID-reuse semantics, unknown-message disconnect behavior, read_all_gtids() stop conditions, and incomplete/empty buffer handling. This is a solid safety net for the GTID parser behavior.


14-17: No action required—harness integration is correct and includes follow the established pattern.

The file is properly registered in test/tap/tests/unit/Makefile (line 290) and uses the correct headers. Like the similar pure data-structure GTID tests (gtid_set_unit-t.cpp, gtid_trxid_interval_unit-t.cpp), gtid_server_data_unit-t.cpp intentionally includes only tap.h and the project header—omitting test_globals.h and test_init.h is correct for data-structure parsing tests that do not depend on ProxySQL runtime globals.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 5, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot

See analysis details on SonarQube Cloud

@renecannao renecannao merged commit c75e222 into v3.0 Apr 13, 2026
6 of 7 checks passed
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.

3 participants