Skip to content

Commit eeb29e0

Browse files
authored
Ensure ltree works (#548)
1 parent 3cac957 commit eeb29e0

File tree

4 files changed

+67
-17
lines changed

4 files changed

+67
-17
lines changed

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,20 @@ extension String: PostgresDecodable {
3636
// we can force unwrap here, since this method only fails if there are not enough
3737
// bytes available.
3838
self = buffer.readString(length: buffer.readableBytes)!
39+
3940
case (_, .uuid):
4041
guard let uuid = try? UUID(from: &buffer, type: .uuid, format: format, context: context) else {
4142
throw PostgresDecodingError.Code.failure
4243
}
4344
self = uuid.uuidString
45+
4446
default:
45-
throw PostgresDecodingError.Code.typeMismatch
47+
// We should eagerly try to convert any datatype into a String. For example the oid
48+
// for ltree isn't static. For this reason we should just try to convert anything.
49+
guard let string = buffer.readString(length: buffer.readableBytes) else {
50+
throw PostgresDecodingError.Code.typeMismatch
51+
}
52+
self = string
4653
}
4754
}
4855
}

Tests/IntegrationTests/PostgresClientTests.swift

+55
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,61 @@ final class PostgresClientTests: XCTestCase {
292292
XCTFail("Unexpected error: \(String(reflecting: error))")
293293
}
294294
}
295+
296+
func testLTree() async throws {
297+
let tableName = "test_client_ltree"
298+
299+
var mlogger = Logger(label: "test")
300+
mlogger.logLevel = .debug
301+
let logger = mlogger
302+
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 8)
303+
self.addTeardownBlock {
304+
try await eventLoopGroup.shutdownGracefully()
305+
}
306+
307+
let clientConfig = PostgresClient.Configuration.makeTestConfiguration()
308+
let client = PostgresClient(configuration: clientConfig, eventLoopGroup: eventLoopGroup, backgroundLogger: logger)
309+
310+
try await withThrowingTaskGroup(of: Void.self) { taskGroup in
311+
taskGroup.addTask {
312+
await client.run()
313+
}
314+
315+
try await client.query("CREATE EXTENSION IF NOT EXISTS ltree;")
316+
317+
try await client.query("DROP TABLE IF EXISTS \"\(unescaped: tableName)\";")
318+
319+
try await client.query(
320+
"""
321+
CREATE TABLE IF NOT EXISTS "\(unescaped: tableName)" (
322+
id SERIAL PRIMARY KEY,
323+
label ltree NOT NULL
324+
);
325+
"""
326+
)
327+
328+
try await client.query(
329+
"""
330+
INSERT INTO "\(unescaped: tableName)" (label) VALUES ('foo.bar.baz')
331+
"""
332+
)
333+
334+
let rows = try await client.query(
335+
"""
336+
SELECT id, label FROM "\(unescaped: tableName)" WHERE label ~ 'foo.*'
337+
"""
338+
)
339+
340+
var count = 0
341+
for try await (id, label) in rows.decode((Int, String).self) {
342+
count += 1
343+
}
344+
XCTAssertEqual(count, 1)
345+
346+
taskGroup.cancelAll()
347+
}
348+
}
349+
295350
}
296351

297352
@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)

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

-12
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,6 @@ class String_PSQLCodableTests: XCTestCase {
3131
}
3232
}
3333

34-
func testDecodeFailureFromInvalidType() {
35-
let buffer = ByteBuffer()
36-
let dataTypes: [PostgresDataType] = [.bool, .float4Array, .float8Array]
37-
38-
for dataType in dataTypes {
39-
var loopBuffer = buffer
40-
XCTAssertThrowsError(try String(from: &loopBuffer, type: dataType, format: .binary, context: .default)) {
41-
XCTAssertEqual($0 as? PostgresDecodingError.Code, .typeMismatch)
42-
}
43-
}
44-
}
45-
4634
func testDecodeFromUUID() {
4735
let uuid = UUID()
4836
var buffer = ByteBuffer()

Tests/PostgresNIOTests/New/PostgresRowTests.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ final class PostgresRowTests: XCTestCase {
172172
name: "name",
173173
tableOID: 1,
174174
columnAttributeNumber: 1,
175-
dataType: .int8,
175+
dataType: .text,
176176
dataTypeSize: 0,
177177
dataTypeModifier: 0,
178178
format: .binary
@@ -185,7 +185,7 @@ final class PostgresRowTests: XCTestCase {
185185
columns: rowDescription
186186
)
187187

188-
XCTAssertThrowsError(try row.decode((UUID?, String).self)) { error in
188+
XCTAssertThrowsError(try row.decode((UUID?, Int).self)) { error in
189189
guard let psqlError = error as? PostgresDecodingError else { return XCTFail("Unexpected error type") }
190190

191191
XCTAssertEqual(psqlError.columnName, "name")
@@ -194,8 +194,8 @@ final class PostgresRowTests: XCTestCase {
194194
XCTAssertEqual(psqlError.file, #fileID)
195195
XCTAssertEqual(psqlError.postgresData, ByteBuffer(integer: 123))
196196
XCTAssertEqual(psqlError.postgresFormat, .binary)
197-
XCTAssertEqual(psqlError.postgresType, .int8)
198-
XCTAssert(psqlError.targetType == String.self)
197+
XCTAssertEqual(psqlError.postgresType, .text)
198+
XCTAssert(psqlError.targetType == Int.self)
199199
}
200200
}
201201
}

0 commit comments

Comments
 (0)