Skip to content

Commit e71d7f0

Browse files
rtolsmaclaude
andcommitted
fix(mysql): Make :execlastid respect big number options
The bigint column mapping already honored support_big_numbers / big_number_strings, but :execlastid always returned Promise<number>, so AUTO_INCREMENT bigint keys silently lied about their type. The insert id now follows the same rules as bigint columns: big_number_strings returns string (converted with String(), since the driver returns big values as strings while the mysql2 typings declare insertId as number), support_big_numbers alone returns number | string, and the default stays number. Verified against the node-mysql2 example (both options enabled), which now returns Promise<string>, and the bun-mysql2 example (no options), which is unchanged; both outputs compile with the examples' tsconfig. Fixes #22. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GFyrFwpJC2eivaBRyNBJqv
1 parent 9198dca commit e71d7f0

2 files changed

Lines changed: 43 additions & 11 deletions

File tree

‎examples/node-mysql2/src/db/query_sql.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ export interface CreateAuthorReturnIdArgs {
9393
bio: string | null;
9494
}
9595

96-
export async function createAuthorReturnId(client: Client, args: CreateAuthorReturnIdArgs): Promise<number> {
96+
export async function createAuthorReturnId(client: Client, args: CreateAuthorReturnIdArgs): Promise<string> {
9797
const [result] = await client.query<ResultSetHeader>({
9898
sql: createAuthorReturnIdQuery,
9999
values: [args.name, args.bio]
100100
});
101-
return result?.insertId ?? 0;
101+
return String(result?.insertId ?? 0);
102102
}
103103

104104
export const deleteAuthorQuery = `-- name: DeleteAuthor :exec

‎src/drivers/mysql2.ts‎

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SyntaxKind, NodeFlags, TypeNode, factory } from "typescript";
1+
import { Expression, SyntaxKind, NodeFlags, TypeNode, factory } from "typescript";
22

33
// import { writeFileSync, STDIO } from "javy/fs";
44

@@ -45,6 +45,20 @@ function funcParamsDecl(iface: string | undefined, params: Parameter[]) {
4545
return funcParams;
4646
}
4747

48+
// The mysql2 types declare insertId as a number, but with
49+
// big_number_strings enabled the driver returns big values as strings, so
50+
// convert explicitly to match the declared return type
51+
function insertIdExpr(value: Expression, options: Mysql2Options): Expression {
52+
if (options.support_big_numbers && options.big_number_strings) {
53+
return factory.createCallExpression(
54+
factory.createIdentifier("String"),
55+
undefined,
56+
[value]
57+
);
58+
}
59+
return value;
60+
}
61+
4862
export class Driver {
4963
private readonly options: Mysql2Options
5064
private readonly customType: CustomTypeFn;
@@ -658,6 +672,21 @@ export class Driver {
658672
) {
659673
const funcParams = funcParamsDecl(argIface, params);
660674

675+
// Mirror the bigint column mapping: with support_big_numbers the driver
676+
// may return the last insert id as a string, and with big_number_strings
677+
// it always does
678+
let insertIdType: TypeNode = factory.createKeywordTypeNode(
679+
SyntaxKind.NumberKeyword
680+
);
681+
if (this.options.support_big_numbers) {
682+
insertIdType = this.options.big_number_strings
683+
? factory.createKeywordTypeNode(SyntaxKind.StringKeyword)
684+
: factory.createUnionTypeNode([
685+
factory.createKeywordTypeNode(SyntaxKind.NumberKeyword),
686+
factory.createKeywordTypeNode(SyntaxKind.StringKeyword),
687+
]);
688+
}
689+
661690
return factory.createFunctionDeclaration(
662691
[
663692
factory.createToken(SyntaxKind.ExportKeyword),
@@ -668,7 +697,7 @@ export class Driver {
668697
undefined,
669698
funcParams,
670699
factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [
671-
factory.createTypeReferenceNode("number", undefined),
700+
insertIdType,
672701
]),
673702
factory.createBlock(
674703
[
@@ -732,14 +761,17 @@ export class Driver {
732761
)
733762
),
734763
factory.createReturnStatement(
735-
factory.createBinaryExpression(
736-
factory.createPropertyAccessChain(
737-
factory.createIdentifier("result"),
738-
factory.createToken(SyntaxKind.QuestionDotToken),
739-
factory.createIdentifier("insertId")
764+
insertIdExpr(
765+
factory.createBinaryExpression(
766+
factory.createPropertyAccessChain(
767+
factory.createIdentifier("result"),
768+
factory.createToken(SyntaxKind.QuestionDotToken),
769+
factory.createIdentifier("insertId")
770+
),
771+
factory.createToken(SyntaxKind.QuestionQuestionToken),
772+
factory.createNumericLiteral(0)
740773
),
741-
factory.createToken(SyntaxKind.QuestionQuestionToken),
742-
factory.createNumericLiteral(0)
774+
this.options
743775
)
744776
),
745777
],

0 commit comments

Comments
 (0)