diff --git a/src/sql/mysql/MySQLTypes.zig b/src/sql/mysql/MySQLTypes.zig index 915dd0ffda..16700893be 100644 --- a/src/sql/mysql/MySQLTypes.zig +++ b/src/sql/mysql/MySQLTypes.zig @@ -247,7 +247,7 @@ pub const FieldType = enum(u8) { MYSQL_TYPE_NULL = 0x06, MYSQL_TYPE_TIMESTAMP = 0x07, MYSQL_TYPE_LONGLONG = 0x08, - MYSQL_TYPE_INT24 = 0x09, + MYSQL_TYPE_INT24 = 0x09, // MEDIUMINT MYSQL_TYPE_DATE = 0x0a, MYSQL_TYPE_TIME = 0x0b, MYSQL_TYPE_DATETIME = 0x0c, diff --git a/src/sql/mysql/protocol/DecodeBinaryValue.zig b/src/sql/mysql/protocol/DecodeBinaryValue.zig index 0cc4e448ef..e557383ed5 100644 --- a/src/sql/mysql/protocol/DecodeBinaryValue.zig +++ b/src/sql/mysql/protocol/DecodeBinaryValue.zig @@ -25,6 +25,17 @@ pub fn decodeBinaryValue(globalObject: *jsc.JSGlobalObject, field_type: types.Fi } return SQLDataCell{ .tag = .int4, .value = .{ .int4 = try reader.int(i16) } }; }, + .MYSQL_TYPE_INT24 => { + if (raw) { + var data = try reader.read(3); + defer data.deinit(); + return SQLDataCell.raw(&data); + } + if (unsigned) { + return SQLDataCell{ .tag = .uint4, .value = .{ .uint4 = try reader.int(u24) } }; + } + return SQLDataCell{ .tag = .int4, .value = .{ .int4 = try reader.int(i24) } }; + }, .MYSQL_TYPE_LONG => { if (raw) { var data = try reader.read(4); diff --git a/src/sql/mysql/protocol/ResultSet.zig b/src/sql/mysql/protocol/ResultSet.zig index 17b96ec83d..d5a06d117f 100644 --- a/src/sql/mysql/protocol/ResultSet.zig +++ b/src/sql/mysql/protocol/ResultSet.zig @@ -73,6 +73,15 @@ pub const Row = struct { cell.* = SQLDataCell{ .tag = .int4, .value = .{ .int4 = val } }; } }, + .MYSQL_TYPE_INT24 => { + if (column.flags.UNSIGNED) { + const val: u24 = std.fmt.parseInt(u24, value.slice(), 10) catch 0; + cell.* = SQLDataCell{ .tag = .uint4, .value = .{ .uint4 = val } }; + } else { + const val: i24 = std.fmt.parseInt(i24, value.slice(), 10) catch std.math.minInt(i24); + cell.* = SQLDataCell{ .tag = .int4, .value = .{ .int4 = val } }; + } + }, .MYSQL_TYPE_LONGLONG => { if (column.flags.UNSIGNED) { const val: u64 = std.fmt.parseInt(u64, value.slice(), 10) catch 0; diff --git a/test/js/sql/sql-mysql.test.ts b/test/js/sql/sql-mysql.test.ts index 5fde68680a..379d7df2b3 100644 --- a/test/js/sql/sql-mysql.test.ts +++ b/test/js/sql/sql-mysql.test.ts @@ -276,6 +276,16 @@ describeWithContainer( expect((await sql`select ${"hello"} as x`)[0].x).toBe("hello"); }); + test("MediumInt/Int24", async () => { + let random_name = ("t_" + Bun.randomUUIDv7("hex").replaceAll("-", "")).toLowerCase(); + await sql`CREATE TEMPORARY TABLE ${sql(random_name)} (a mediumint unsigned)`; + await sql`INSERT INTO ${sql(random_name)} VALUES (${1})`; + const result = await sql`select * from ${sql(random_name)}`; + expect(result[0].a).toBe(1); + const result2 = await sql`select * from ${sql(random_name)}`.simple(); + expect(result2[0].a).toBe(1); + }); + test("Boolean/TinyInt/BIT", async () => { // Protocol will always return 0 or 1 for TRUE and FALSE when not using a table. expect((await sql`select ${false} as x`)[0].x).toBe(0);