Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 69d8595

Browse files
authored
Add workaround for decoding NUMERIC as Double (vapor#243)
Add workaround to tolerate Fluent's assumption that `NUMERIC` can be decoded to `Double` (but not `Float` or `Int`, naturally).
1 parent 3976618 commit 69d8595

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

‎Sources/PostgresKit/PostgresDataTranslation.swift‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ struct PostgresDataTranslation {
4242
cellToDecode = PostgresCell(bytes: cell.bytes, dataType: .name, format: cell.format, columnName: cell.columnName, columnIndex: cell.columnIndex)
4343
} else if cell.format == .binary && [.char, .varchar, .text].contains(cell.dataType) && T.self is Decimal.Type { // Workaround cheat for Fluent's assumption that Decimal strings work
4444
cellToDecode = PostgresCell(bytes: cell.bytes, dataType: .numeric, format: .text, columnName: cell.columnName, columnIndex: cell.columnIndex)
45+
} else if cell.format == .binary && cell.dataType == .numeric && T.self is Double.Type { // Workaround cheat for Fluent's expectation that Postgres's `numeric/decimal` can be decoded as Double
46+
// Extremely manual workaround...
47+
guard let value = PostgresData(type: cell.dataType, formatCode: cell.format, value: cell.bytes).numeric?.double else {
48+
throw DecodingError.dataCorrupted(.init(codingPath: codingPath, debugDescription: "Invalid numeric value encoding"))
49+
}
50+
return value as! T
4551
} else {
4652
cellToDecode = cell
4753
}

‎Tests/PostgresKitTests/PostgresKitTests.swift‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,22 @@ final class PostgresKitTests: XCTestCase {
208208
XCTAssertEqual(decoded1.prop3, instance.prop3)
209209
XCTAssertEqual(decoded2.count, 2)
210210
}
211+
212+
func testFluentWorkaroundsDecoding() throws {
213+
// SQLKit benchmarks already test enum handling
214+
215+
// Text encoding for Decimal
216+
let decimalBuffer = ByteBuffer(string: Decimal(12345.6789).description)
217+
var decimalValue: Decimal?
218+
XCTAssertNoThrow(decimalValue = try PostgresDataTranslation.decode(Decimal.self, from: .init(bytes: decimalBuffer, dataType: .numeric, format: .text, columnName: "", columnIndex: -1), in: .default))
219+
XCTAssertEqual(decimalValue, Decimal(12345.6789))
220+
221+
// Decoding Double from NUMERIC
222+
let numericBuffer = PostgresData(numeric: .init(decimal: 12345.6789)).value
223+
var numericValue: Double?
224+
XCTAssertNoThrow(numericValue = try PostgresDataTranslation.decode(Double.self, from: .init(bytes: numericBuffer, dataType: .numeric, format: .binary, columnName: "", columnIndex: -1), in: .default))
225+
XCTAssertEqual(numericValue, Double(Decimal(12345.6789).description))
226+
}
211227

212228
var eventLoop: any EventLoop { self.eventLoopGroup.any() }
213229
var eventLoopGroup: (any EventLoopGroup)!

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /