diff --git a/build.zig b/build.zig index a3275d3..e845702 100644 --- a/build.zig +++ b/build.zig @@ -70,6 +70,7 @@ pub fn build(b: *std.Build) !void { .test_runner = .{ .path = b.path("test_runner.zig"), .mode = .simple }, }); addLibs(lib_test, modules); + lib_test.linkLibC(); lib_test.addLibraryPath(std.Build.LazyPath{ .cwd_relative = "/opt/openssl/lib" }); lib_test.addIncludePath(std.Build.LazyPath{ .cwd_relative = "/opt/openssl/include" }); lib_test.linkSystemLibrary("crypto"); diff --git a/src/result.zig b/src/result.zig index b47cf9f..0d0ccd4 100644 --- a/src/result.zig +++ b/src/result.zig @@ -1252,6 +1252,17 @@ test "Result: UUID" { try t.expectSlice(u8, &.{ 174, 47, 71, 95, 128, 112, 65, 183, 186, 51, 134, 187, 168, 137, 123, 222 }, row.get([]u8, 1)); } +test "Result: lsn" { + var c = t.connect(.{}); + defer c.deinit(); + const sql = "select $1::pg_lsn + 1"; + var result = try c.query(sql, .{ 32788447688 }); + defer result.deinit(); + + const row = (try result.next()).?; + try t.expectEqual(32788447689, row.get(i64, 0)); +} + test "Row: column names" { var c = t.connect(.{}); defer c.deinit(); diff --git a/src/types.zig b/src/types.zig index 2406ca9..a49dbe9 100644 --- a/src/types.zig +++ b/src/types.zig @@ -93,7 +93,7 @@ pub const Int32 = struct { } pub fn decode(data: []const u8, data_oid: i32) i32 { - lib.assertDecodeType(i32, &.{Int32.oid.decimal}, data_oid); + lib.assertDecodeType(i32, &.{Int32.oid.decimal, Xid.oid.decimal}, data_oid); return Int32.decodeKnown(data); } @@ -119,9 +119,9 @@ pub const Int64 = struct { pub fn decode(data: []const u8, data_oid: i32) i64 { switch (data_oid) { - Timestamp.oid.decimal, TimestampTz.oid.decimal => return Timestamp.decode(data, data_oid), + Timestamp.oid.decimal, TimestampTz.oid.decimal => return Timestamp.decodeKnown(data), else => { - lib.assertDecodeType(i64, &.{Int64.oid.decimal}, data_oid); + lib.assertDecodeType(i64, &.{Int64.oid.decimal, PgLSN.oid.decimal, Xid8.oid.decimal}, data_oid); return Int64.decodeKnown(data); }, } @@ -368,6 +368,21 @@ pub const UUID = struct { } }; +pub const PgLSN = struct { + pub const oid = OID.make(3220); + const encoding = &binary_encoding; +}; + +pub const Xid = struct { + pub const oid = OID.make(28); + const encoding = &binary_encoding; +}; + +pub const Xid8 = struct { + pub const oid = OID.make(5069); + const encoding = &binary_encoding; +}; + pub const MacAddr = struct { pub const oid = OID.make(829); const encoding = &binary_encoding; @@ -1137,7 +1152,7 @@ pub fn bindValue(comptime T: type, oid: i32, value: anytype, buf: *buffer.Buffer if (value > 255 or value < 0) return error.IntWontFit; return Char.encode(@intCast(value), buf, format_pos); }, - Int64.oid.decimal => return Int64.encode(@intCast(value), buf, format_pos), + Int64.oid.decimal, PgLSN.oid.decimal => return Int64.encode(@intCast(value), buf, format_pos), else => return error.BindWrongType, }, .int => switch (oid) { -- 2.51.2 From 97e28a31960a8aeaaebdd13232d1cbed36600bea Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sun, 17 Aug 2025 10:13:37 +0800 Subject: [PATCH 2/3] better support for lsn/xid --- src/types.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types.zig b/src/types.zig index a49dbe9..cd470a9 100644 --- a/src/types.zig +++ b/src/types.zig @@ -1152,7 +1152,7 @@ pub fn bindValue(comptime T: type, oid: i32, value: anytype, buf: *buffer.Buffer if (value > 255 or value < 0) return error.IntWontFit; return Char.encode(@intCast(value), buf, format_pos); }, - Int64.oid.decimal, PgLSN.oid.decimal => return Int64.encode(@intCast(value), buf, format_pos), + Int64.oid.decimal, PgLSN.oid.decimal, Xid8.oid.decimal => return Int64.encode(@intCast(value), buf, format_pos), else => return error.BindWrongType, }, .int => switch (oid) { @@ -1160,7 +1160,7 @@ pub fn bindValue(comptime T: type, oid: i32, value: anytype, buf: *buffer.Buffer if (value > 32767 or value < -32768) return error.IntWontFit; return Int16.encode(@intCast(value), buf, format_pos); }, - Int32.oid.decimal => { + Int32.oid.decimal, Xid.oid.decimal => { if (value > 2147483647 or value < -2147483648) return error.IntWontFit; return Int32.encode(@intCast(value), buf, format_pos); }, @@ -1170,7 +1170,7 @@ pub fn bindValue(comptime T: type, oid: i32, value: anytype, buf: *buffer.Buffer if (value > 255 or value < 0) return error.IntWontFit; return Char.encode(@intCast(value), buf, format_pos); }, - Int64.oid.decimal => { + Int64.oid.decimal, PgLSN.oid.decimal, Xid8.oid.decimal => { if (value > 9223372036854775807 or value < -9223372036854775808) { return error.IntWontFit; } -- 2.51.2 From 1d6df57393c9b1dcf4a4b4d057a0f098923a160e Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 19 Aug 2025 08:10:17 +0800 Subject: [PATCH 3/3] add pglsn and xid(8) types to readme --- readme.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readme.md b/readme.md index f2cc80d..6081c14 100644 --- a/readme.md +++ b/readme.md @@ -518,6 +518,11 @@ When binding to an array of JSON or JSONB, automatic serialization is not suppor When reading a `JSON` or `JSONB` column with `[]u8`, the serialized JSON will be returned. +### PgLSN, xid8, xid +PgLSN and xid8 can be bound and read as i64. + +xid can be bound and read as i32. + ## Listen / Notify You can create a `pg.Listener` either from an existing `Pool` or directly.