Skip to content

Commit d50aade

Browse files
authored
Fix: Correctly decode jsonb to String by stripping version byte (#568)
1 parent c17db2f commit d50aade

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

Sources/PostgresNIO/New/Data/String+PostgresCodable.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ extension String: PostgresDecodable {
2929
context: PostgresDecodingContext<JSONDecoder>
3030
) throws {
3131
switch (format, type) {
32+
case (.binary, .jsonb):
33+
// Discard the version byte
34+
guard let version = buffer.readInteger(as: UInt8.self), version == 1 else {
35+
throw PostgresDecodingError.Code.failure
36+
}
37+
self = buffer.readString(length: buffer.readableBytes)!
3238
case (_, .varchar),
3339
(_, .bpchar),
3440
(_, .text),

Tests/IntegrationTests/PostgresNIOTests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,22 @@ final class PostgresNIOTests: XCTestCase {
930930
}
931931
}
932932

933+
func testJSONBDecodeString() {
934+
var conn: PostgresConnection?
935+
XCTAssertNoThrow(conn = try PostgresConnection.test(on: eventLoop).wait())
936+
defer { XCTAssertNoThrow(try conn?.close().wait()) }
937+
938+
do {
939+
var rows: PostgresQueryResult?
940+
XCTAssertNoThrow(rows = try conn?.query("select '{\"hello\": \"world\"}'::jsonb as data").wait())
941+
942+
var resultString: String?
943+
XCTAssertNoThrow(resultString = try rows?.first?.decode(String.self, context: .default))
944+
945+
XCTAssertEqual(resultString, "{\"hello\": \"world\"}")
946+
}
947+
}
948+
933949
func testInt4RangeSerialize() async throws {
934950
let conn: PostgresConnection = try await PostgresConnection.test(on: eventLoop).get()
935951
self.addTeardownBlock {

Tests/PostgresNIOTests/New/Data/String+PSQLCodableTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,15 @@ class String_PSQLCodableTests: XCTestCase {
5252
XCTAssertEqual($0 as? PostgresDecodingError.Code, .failure)
5353
}
5454
}
55+
56+
func testDecodeFromJSONB() {
57+
let json = #"{"hello": "world"}"#
58+
var buffer = ByteBuffer()
59+
buffer.writeInteger(UInt8(1))
60+
buffer.writeString(json)
61+
62+
var decoded: String?
63+
XCTAssertNoThrow(decoded = try String(from: &buffer, type: .jsonb, format: .binary, context: .default))
64+
XCTAssertEqual(decoded, json)
65+
}
5566
}

0 commit comments

Comments
 (0)