Skip to content

fix(mysql): prevent panic on NULL values and hanging connections with OceanBase - #114

Merged
Blankll merged 2 commits into
masterfrom
fix/mysql-oceanbase-connection
Jun 23, 2026
Merged

fix(mysql): prevent panic on NULL values and hanging connections with OceanBase#114
Blankll merged 2 commits into
masterfrom
fix/mysql-oceanbase-connection

Conversation

@Blankll

@Blankll Blankll commented Jun 22, 2026

Copy link
Copy Markdown
Member

Problem

Connecting to OceanBase (MySQL-compatible) has two critical issues:

1. Panic on NULL values in test_connection()

thread 'tokio-rt-worker' panicked at mysql_common/src/value/convert/mod.rs:122:23:
Could not retrieve `alloc::string::String`: Couldn't convert the value `Null` to a desired type

row.get::<String, _>().unwrap() uses FromValue for String which panic!s on Value::NULL. OceanBase returns NULL for DATABASE() when no database is selected, and potentially for USER() depending on configuration.

2. Connection hangs indefinitely

MySQLAdapter::connect() had no internal connection timeout. The tcp_connect_timeout API was removed in mysql_async v0.34 with no replacement, so pool.get_conn().await could hang forever on unresponsive hosts.

The tokio::time::timeout in connect_server only covers one code path — the "Test Connection" dialog path (server::test_connection) calls connect() directly with zero timeout protection.

Fix

1. Safe NULL handling in test_connection()

Replaced row.get::<String, _>().unwrap() with row.get_opt::<String, _>() which returns Option<Result<String, FromValueError>>. A match on Some(Ok(val)) gracefully resolves NULL to None instead of panicking.

2. Adapter-level connection timeout

Added tokio::time::timeout wrapping pool.get_conn() and conn.query_drop(\"SELECT 1\") inside connect(), using self.config.connect_timeout_secs. This applies to ALL call paths (both "Connect" and "Test Connection") since the timeout lives at the adapter level.

Testing

  • ✅ All 268 existing unit tests pass
  • ✅ All 26 integration tests pass
  • ✅ No regressions in MySQL adapter tests
  • cargo check clean

Blankll and others added 2 commits June 23, 2026 00:53
… OceanBase

Two fixes for MySQL adapter when connecting to OceanBase:

1. test_connection() used row.get::<String, _>().unwrap() which panics
   when the database returns NULL (e.g. DATABASE() with no database
   selected). Changed to use get_opt() which returns Option<Result<_, _>>
   and gracefully handles NULL -> None.

2. connect() had no internal connection timeout — mysql_async v0.34
   removed tcp_connect_timeout, so pool.get_conn() could hang forever
   on unresponsive hosts. Added tokio::time::timeout wrapping both
   get_conn() and query_drop("SELECT 1") using connect_timeout_secs.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…rdcoded timeouts

Four HTTP-based adapters used hardcoded timeouts (ClickHouse/Turso/RQLite: 60s, HttpSql: 30s) instead of respecting the user's configured connect_timeout_secs from ConnectionConfig.

- clickhouse.rs: build_client() 60s hardcoded -> connect_timeout_secs
- turso.rs: build_client() 60s hardcoded -> connect_timeout_secs
- rqlite.rs: build_client() 60s hardcoded -> connect_timeout_secs
- http_sql.rs: connect() 30s hardcoded -> connect_timeout_secs

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@Blankll
Blankll merged commit dbd1b9b into master Jun 23, 2026
3 checks passed
@Blankll
Blankll deleted the fix/mysql-oceanbase-connection branch June 23, 2026 08:41
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.

1 participant