Skip to content

fix: use mysql binary protocol to avoid a lossy conversion#29285

Merged
jacek-prisma merged 2 commits intomainfrom
fix/use-mysql-binary-protocol
Mar 9, 2026
Merged

fix: use mysql binary protocol to avoid a lossy conversion#29285
jacek-prisma merged 2 commits intomainfrom
fix/use-mysql-binary-protocol

Conversation

@jacek-prisma
Copy link
Contributor

@jacek-prisma jacek-prisma commented Mar 2, 2026

TML-1899

Fixes #29160

Modifies the mariadb adapter to use the binary protocol whenever possible. This solves some edge cases with serializing large numbers.
Also changed the adapter to use phantom queries, because the driver does not support transactions in its binary protocol, so it has to issue query calls directly.

Summary by CodeRabbit

  • Bug Fixes

    • Improved MariaDB adapter transaction and query behavior to avoid protocol-related issues; made commit/rollback/savepoint operations more robust and error-safe.
  • Tests

    • Added end-to-end tests validating large-decimal precision on MySQL.
    • Added test matrix/schema wiring for MySQL precision scenarios.
    • Updated tracing tests to include MariaDB/MySQL driver scenarios.
    • Relaxed float assertions in MySQL scalar tests to allow Float32 representation variance.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 2, 2026

Walkthrough

Non-transactional operations now use the binary-protocol execute while all transaction-related SQL (BEGIN, COMMIT, ROLLBACK, savepoints) use the text-protocol query to avoid binary-protocol issues; transaction connection is made readonly and phantom queries are enabled for transactions. Adds MySQL functional tests for large-Decimal increment/decrement and relaxes float assertions and tracing synthetic-query handling for MariaDB/MySQL.

Changes

Cohort / File(s) Summary
MariaDB adapter
packages/adapter-mariadb/src/mariadb.ts
performIO uses client.execute for normal data operations; all transaction operations (BEGIN, COMMIT, ROLLBACK, savepoints) use client.query to avoid the binary protocol; transaction constructor conn made readonly; TransactionOptions.usePhantomQuery set to true; added comments and onError handling around transaction queries.
MySQL Decimal precision tests
packages/client/tests/functional/issues/29160-mysql-precision-loss/_matrix.ts, packages/client/tests/functional/issues/29160-mysql-precision-loss/prisma/_schema.ts, packages/client/tests/functional/issues/29160-mysql-precision-loss/tests.ts
Adds test matrix, Prisma schema (AssetAccount with Decimal(30,0)), and a functional test performing large Decimal increment/decrement sequences that assert exact precision for MySQL; opts out non-MySQL providers and skips Planetscale.
Test adjustments for drivers & floats
packages/client/tests/functional/tracing/tests.ts, packages/client/tests/functional/typed-sql/mysql-scalars-nullable/test.ts, packages/client/tests/functional/typed-sql/mysql-scalars/test.ts
Includes js_mariadb in synthetic-query handling and extends remote-provider checks for synthetic transactions; relaxes float assertions to accept either exact value or Float32-derived value to account for MySQL/MariaDB float precision behavior.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main change: using MySQL binary protocol to avoid lossy conversion for large Decimal values.
Linked Issues check ✅ Passed The PR addresses issue #29160 by modifying MariaDB adapter to use binary protocol (via client.execute) for normal operations while avoiding it for transactions, adding comprehensive tests for precision preservation with large Decimals.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing precision loss with large Decimal values: adapter modifications for binary protocol usage, new test matrix/schema/tests for issue #29160, and updates to existing tests to account for precision handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/use-mysql-binary-protocol

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
Contributor

@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.

Caution

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

⚠️ Outside diff range comments (1)
packages/adapter-mariadb/src/mariadb.ts (1)

170-177: ⚠️ Potential issue | 🟠 Major

SET TRANSACTION ISOLATION LEVEL should use query() instead of executeRaw().

Line 170 uses tx.executeRaw() (which calls client.execute(), the binary protocol), but the class explicitly documents that all transaction operations must use client.query() to avoid the binary protocol, which does not reliably support transactions in the MariaDB driver. The BEGIN statement correctly uses query() on line 177. This inconsistency violates the stated design principle and should be fixed.

Proposed fix
 if (isolationLevel) { - await tx.executeRaw({ - sql: `SET TRANSACTION ISOLATION LEVEL ${isolationLevel}`, - args: [], - argTypes: [], - }) + await tx.conn + .query({ sql: `SET TRANSACTION ISOLATION LEVEL ${isolationLevel}` }) + .catch(this.onError.bind(this)) } // Uses `query` instead of `execute` to avoid the binary protocol. await tx.conn.query({ sql: 'BEGIN' }).catch(this.onError.bind(this))

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6738298 and 2288e3a.

📒 Files selected for processing (4)
  • packages/adapter-mariadb/src/mariadb.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/_matrix.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/prisma/_schema.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/tests.ts
@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

size-limit report 📦

Path Size
packages/client/runtime/index-browser.js 2.23 KB (0%)
packages/client/runtime/index-browser.d.ts 3.28 KB (0%)
packages/cli/build/index.js 2.5 MB (0%)
packages/client/prisma-client-0.0.0.tgz 26.81 MB (-0.01% 🔽)
packages/cli/prisma-0.0.0.tgz 12.84 MB (0%)
packages/bundle-size/da-workers-libsql/output.tgz 1.33 MB (0%)
packages/bundle-size/da-workers-neon/output.tgz 1.39 MB (0%)
packages/bundle-size/da-workers-pg/output.tgz 1.38 MB (0%)
packages/bundle-size/da-workers-planetscale/output.tgz 1.33 MB (0%)
packages/bundle-size/da-workers-d1/output.tgz 1.3 MB (0%)
@jacek-prisma jacek-prisma force-pushed the fix/use-mysql-binary-protocol branch 2 times, most recently from 7fc6470 to 600cc77 Compare March 3, 2026 11:55
Copy link
Contributor

@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: 2


ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2288e3a and 600cc77.

📒 Files selected for processing (7)
  • packages/adapter-mariadb/src/mariadb.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/_matrix.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/prisma/_schema.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/tests.ts
  • packages/client/tests/functional/tracing/tests.ts
  • packages/client/tests/functional/typed-sql/mysql-scalars-nullable/test.ts
  • packages/client/tests/functional/typed-sql/mysql-scalars/test.ts
@jacek-prisma jacek-prisma force-pushed the fix/use-mysql-binary-protocol branch from 600cc77 to ce0e921 Compare March 3, 2026 12:29
Copy link
Contributor

@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)
packages/adapter-mariadb/src/mariadb.ts (1)

170-178: ⚠️ Potential issue | 🟠 Major

Keep isolation-level setup on query path (not executeRaw).

Line 181 routes SET TRANSACTION ISOLATION LEVEL through executeRaw (binary protocol), but the class comment explicitly states "All transaction operations use client.query instead of client.execute to avoid using the binary protocol, which does not support transactions in the MariaDB driver." All other transaction control statements—BEGIN (line 188), COMMIT (line 95), ROLLBACK (line 108), and SAVEPOINT operations—use client.query. This inconsistency violates the established pattern and may break transaction support.

Proposed fix
 if (isolationLevel) { - await tx.executeRaw({ - sql: `SET TRANSACTION ISOLATION LEVEL ${isolationLevel}`, - args: [], - argTypes: [], - }) + await tx.conn.query({ + sql: `SET TRANSACTION ISOLATION LEVEL ${isolationLevel}`, + }).catch(this.onError.bind(this)) }
♻️ Duplicate comments (2)
packages/client/tests/functional/issues/29160-mysql-precision-loss/prisma/_schema.ts (1)

14-17: ⚠️ Potential issue | 🟠 Major

Pin the model column to Decimal(30,0) for regression fidelity.

At Line 16, unconstrained Decimal can miss the exact failure mode from issue #29160 (Decimal(30,0)).

Proposed fix
 model AssetAccount { assetId ${idForProvider(provider)} - amount Decimal `@default`(0) + amount Decimal `@default`(0) `@db.Decimal`(30, 0) }
packages/adapter-mariadb/src/mariadb.ts (1)

94-104: ⚠️ Potential issue | 🟠 Major

Ensure cleanup/close always run on COMMIT/ROLLBACK failures.

At Line 94 and Line 102, onError throws inside .catch(...), so cleanup and client.end() are skipped on failure.

Proposed fix
 async commit(): Promise<void> { debug(`[js::commit]`) - - await this.client.query({ sql: 'COMMIT' }).catch(this.onError.bind(this)) - this.cleanup?.() - await this.client.end() + try { + await this.client.query({ sql: 'COMMIT' }) + } catch (error) { + this.onError(error) + } finally { + this.cleanup?.() + await this.client.end() + } } async rollback(): Promise<void> { debug(`[js::rollback]`) - - await this.client.query({ sql: 'ROLLBACK' }).catch(this.onError.bind(this)) - this.cleanup?.() - await this.client.end() + try { + await this.client.query({ sql: 'ROLLBACK' }) + } catch (error) { + this.onError(error) + } finally { + this.cleanup?.() + await this.client.end() + } }

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 600cc77 and ce0e921.

📒 Files selected for processing (7)
  • packages/adapter-mariadb/src/mariadb.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/_matrix.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/prisma/_schema.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/tests.ts
  • packages/client/tests/functional/tracing/tests.ts
  • packages/client/tests/functional/typed-sql/mysql-scalars-nullable/test.ts
  • packages/client/tests/functional/typed-sql/mysql-scalars/test.ts
Copy link
Contributor

@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


ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ce0e921 and 338e306.

📒 Files selected for processing (2)
  • packages/adapter-mariadb/src/mariadb.ts
  • packages/client/tests/functional/issues/29160-mysql-precision-loss/prisma/_schema.ts
@jacek-prisma jacek-prisma requested a review from aqrln March 4, 2026 11:40
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Mar 5, 2026
@jacek-prisma jacek-prisma merged commit bee4502 into main Mar 9, 2026
252 of 253 checks passed
@jacek-prisma jacek-prisma deleted the fix/use-mysql-binary-protocol branch March 9, 2026 09:00
jacek-prisma added a commit to prisma/prisma-engines that referenced this pull request Mar 11, 2026
Fixes: - outdated snapshots missing `stripped_partial_indexes` - missing `mariadb-mysql.js.wasm` for some MySQL tests that caused them not to be run - corrects some mysql tests to account for minor change in float precision behavior (see prisma/prisma#29285) /test-all <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Expanded query engine testing to support MariaDB MySQL WASM target compatibility alongside MySQL 8 configurations. * Refactored test validation methodology to use programmatic assertions for improved reliability. * Updated schema describer test expectations to reflect current field handling for index structures. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer

2 participants