feat(plugin-mysql): add TiDB and Databend connection types - #2711
Merged
datlechin merged 11 commits intoSep 11, 2026
Merged
Conversation
Co-authored-by: Nguyễn Nam Long <J2TeamNNL@users.noreply.github.com>
This was referenced Sep 10, 2026
Closed
Co-authored-by: Cursor <cursoragent@cursor.com>
…atabaseType moved to its own file Claude-Session: https://claude.ai/code/session_01Fvgf1oCG7h5qgmMDd8GfN6
…mysql-variants-135e Claude-Session: https://claude.ai/code/session_01EtSNyG8StyXn92NLdMFzsV
Co-authored-by: Cursor <cursoragent@cursor.com>
…n the MySQL driver Claude-Session: https://claude.ai/code/session_01EtSNyG8StyXn92NLdMFzsV
…mysql-variants-135e Claude-Session: https://claude.ai/code/session_01EtSNyG8StyXn92NLdMFzsV
… SHOW CREATE TABLE and never kill an idle TiDB session Claude-Session: https://claude.ai/code/session_01EtSNyG8StyXn92NLdMFzsV
This was referenced Sep 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1066
Fixes #2514
Summary
Adds TiDB and Databend as connection types served by the bundled MySQL plugin. The first version routed both to the unchanged MySQL driver. Measured against live TiDB 7.5.1 / 8.5.1 and Databend 1.2.881 servers, that broke saves, the Structure tab, Stop, Users & Roles and EXPLAIN on one or both. This revision gives the driver a server flavor and fixes each of those paths.
Root cause
The driver's only engine signal was
isMariaDB, read from the version banner. TiDB reports8.0.11-TiDB-v7.5.1and Databend reports8.0.90-v1.2.881-..., so every branch ran them as MySQL 8.0.x. The curated snapshots were copies of MySQL's, so they also inheritedEXPLAIN FORMAT=JSON, lowercase system schemas, MySQL's type list and MySQL's capability flags.What changed
Driver (
Plugins/MySQLDriverPlugin)MySQLServerFlavor(mysql, mariadb, tidb(version), databend) replacesisMariaDB. It is resolved once per connect from the banner plus the connection type.MySQLPlugin.driverVariant(for:)passes the type through the existingadditionalFields["driverVariant"]channel, so there is no PluginKit change. TiDB is also recognised when it is opened as a MySQL connection. A Databend server opened as MySQL fails at connect and asks for the Databend type.KILL TIDB QUERY <SELECT CONNECTION_ID()>. The handshake thread id is truncated to 32 bits, so it missed 64-bit ids. Databend sendsKILL QUERY '<session uuid>'.--skip-ssl, TiDB and Databend. The kill connection now copies the primary connection's negotiated transport.max_user_connections, ANALYZE as the only maintenance operation.SHOW CREATE TABLE. TiDB never lists them inTABLE_CONSTRAINTS, so MySQL's join always came back empty, andTIDB_CHECK_CONSTRAINTSdoes not exist on 7.5.KILL TIDB QUERY(measured on 7.5.1 and 8.5.1; MariaDB ignores it). A read that returns more rows than the cap therefore drains the rest on TiDB instead of killing a statement that may already be finished. Before, anySELECT ... LIMIT 5000under a 1,000-row cap dropped the connection on the next statement, open transaction included.'...'and"...", as Databend's MySQL dialect does, so a scanner and server disagreement can only produce a count mismatch, which is refused.BEGIN.START TRANSACTIONis accepted but ignored, so a rollback kept the rows.number of rows ...result row.SET max_result_rowsand timeouts useSET max_execute_time_in_seconds.system.columnsandsystem.constraints. Routine and trigger reads return nothing instead of querying MySQL catalogs Databend lacks.RENAME COLUMN, fullMODIFY COLUMNrestatement, no keys, indexes, charsets or AUTO_INCREMENT.App
FORMAT=JSON.LOWER()for Databend.rowMatchExcludedTypePrefixesfor Databend.ORcannot widen past what each row matched. A delete the generator cannot identify is refused instead of dropped. A row inserted with every column on its default is written asINSERT ... (col) VALUES (DEFAULT), since Databend rejectsDEFAULT VALUES.mysql://host:3307/..., port kept, instead of an empty://scheme.databend-queryimage of a split deployment.mysqldump --single-transactionfails), no Create Table engine or charset pickers, and no MySQL-to-TiDB Compare scripts. Users & Roles hides the connection limit, which TiDB ignores.pluginTypeId, MySQL SQL-dialect facts throughSqlDialect.from == .mysql(which drops Databend), and type spelling throughSQLTypeFamily.ForeignAppDatabaseType.resolve. The fictional TablePlus TiDB fixture and the unverified NavicatTIDBfixture are gone.databend://is Databend's HTTP connection string, so it stays unsupported.tidb://resolves through the registry.Verification
SLEEP(8)or a long scan.,(,''and\\: listed on 7.5 and 8.5 with the same text asCHECK_CLAUSE.MySQLServerFlavor, Databend literal inlining (including break-out payloads), identifier quoting, result shape, catalog SQL, TiDB check-constraint parsing, variant support decisions, and keyless row-match exclusion.OracleDriver: the third-partyoracle-niofails under the local Xcode 27 beta toolchain with a@TaskLocalmacro error. The same error blocks the iOS app target locally, so CI is the iOS compile check. The widget extension compiled.swiftlint --strictis clean on the touched paths. The docs source check and house-style checks pass.Not in this PR
/v1/query) plugin.tidb_json).Boolparameters are sent as1/0, which Databend refuses for a BOOLEAN column. The grid sendstrue/falsetext and is not affected.SqlDialectcase, which is a PluginKit change; the docs say to write''.https://claude.ai/code/session_01EtSNyG8StyXn92NLdMFzsV