Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Sources/PostgresKit/PostgresDataTranslation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ struct PostgresDataTranslation {
cellToDecode = PostgresCell(bytes: cell.bytes, dataType: .name, format: cell.format, columnName: cell.columnName, columnIndex: cell.columnIndex)
} 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
cellToDecode = PostgresCell(bytes: cell.bytes, dataType: .numeric, format: .text, columnName: cell.columnName, columnIndex: cell.columnIndex)
} 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
// Extremely manual workaround...
guard let value = PostgresData(type: cell.dataType, formatCode: cell.format, value: cell.bytes).numeric?.double else {
throw DecodingError.dataCorrupted(.init(codingPath: codingPath, debugDescription: "Invalid numeric value encoding"))
}
return value as! T
} else {
cellToDecode = cell
}
Expand Down
16 changes: 16 additions & 0 deletions Tests/PostgresKitTests/PostgresKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,22 @@ final class PostgresKitTests: XCTestCase {
XCTAssertEqual(decoded1.prop3, instance.prop3)
XCTAssertEqual(decoded2.count, 2)
}

func testFluentWorkaroundsDecoding() throws {
// SQLKit benchmarks already test enum handling

// Text encoding for Decimal
let decimalBuffer = ByteBuffer(string: Decimal(12345.6789).description)
var decimalValue: Decimal?
XCTAssertNoThrow(decimalValue = try PostgresDataTranslation.decode(Decimal.self, from: .init(bytes: decimalBuffer, dataType: .numeric, format: .text, columnName: "", columnIndex: -1), in: .default))
XCTAssertEqual(decimalValue, Decimal(12345.6789))

// Decoding Double from NUMERIC
let numericBuffer = PostgresData(numeric: .init(decimal: 12345.6789)).value
var numericValue: Double?
XCTAssertNoThrow(numericValue = try PostgresDataTranslation.decode(Double.self, from: .init(bytes: numericBuffer, dataType: .numeric, format: .binary, columnName: "", columnIndex: -1), in: .default))
XCTAssertEqual(numericValue, Double(Decimal(12345.6789).description))
}

var eventLoop: any EventLoop { self.eventLoopGroup.any() }
var eventLoopGroup: (any EventLoopGroup)!
Expand Down