perf(spanner): optimize codec.getType and reuse type singletons - #9366
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors Spanner parameter type resolution in codec.ts to use frozen singletons for parameterless types, reducing heap allocations and GC pressure. It also introduces support for pgJsonb and refactors getType to accept an optional enableUuidAsUntyped parameter. Feedback on the changes suggests exporting and utilizing isUuidUntypedEnv in transaction.ts to ensure deprecation warnings are not bypassed, and caching the parsed environment variable value in codec.ts to avoid performance bottlenecks from repeatedly accessing process.env.
- Reorder type checks in `codec.getType` so common types (primitives, buffers, dates) are evaluated before less frequent wrapper types. - Reuse frozen module singletons for parameterless types to avoid allocating fresh type descriptors on each invocation. - Support `pgJsonb` in `TypeCode` and `createTypeObject`. - Defer reading `SPANNER_ENABLE_UUID_AS_UNTYPED` so it is only checked for string values, and cache the flag during parameter encoding in `Snapshot.encodeParams`.
7b1291f to
4cf327d
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request optimizes Spanner parameter encoding by introducing frozen, parameterless type singletons to reduce heap allocations and GC pressure, alongside refactoring getType and adding support for pgJsonb. Feedback on these changes highlights a critical correctness regression where the omission of the isDecimal(value) check in getType causes custom decimal objects to be incorrectly typed as JSON instead of float64. Additionally, caching the process.env lookup for the deprecated SPANNER_ENABLE_UUID_AS_UNTYPED flag is recommended to avoid performance overhead during high-throughput query parameter encoding.
🤖 I have created a release *beep* *boop* --- ## [9.0.0](spanner-v8.13.0...spanner-v9.0.0) (2026-09-18) ### ⚠ BREAKING CHANGES * **Spanner:** Update cloud-spanner to minimum Node version of 22 ([#9291](#9291)) * **Spanner:** upgrade OpenTelemetry to v2 ([#9329](#9329)) ### Features * **Spanner:** Update cloud-spanner to minimum Node version of 22 ([#9291](#9291)) ([ecd5bfd](ecd5bfd)) * **Spanner:** Upgrade OpenTelemetry to v2 ([#9329](#9329)) ([ed3a44e](ed3a44e)) ### Performance Improvements * **spanner:** Bypass gRPC message interception in metrics interceptor ([#9306](#9306)) ([a44180d](a44180d)) * **spanner:** Disable gRPC channelz by default ([#9320](#9320)) ([11c257b](11c257b)) * **spanner:** Optimize codec.getType and reuse type singletons ([#9366](#9366)) ([1b1b411](1b1b411)) * **spanner:** Remove rest-parameter allocations in wrappedRequestFn ([#9365](#9365)) ([7085e03](7085e03)) * **spanner:** Synchronous multiplexed session hand-off for non-stream callers ([#9362](#9362)) ([dbbc55c](dbbc55c)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
codec.getTypeso common types (primitives, buffers, dates) are evaluated before less frequent wrapper types.pgJsonbinTypeCodeandcreateTypeObject.SPANNER_ENABLE_UUID_AS_UNTYPEDso it is only checked for string values, and cache the flag during parameter encoding inSnapshot.encodeParams.