@@ -108,8 +108,12 @@ private struct _RowDecoder<R: FetchableRecord>: Decoder {
108108
109109 func singleValueContainer( ) throws -> SingleValueDecodingContainer {
110110 guard let key = codingPath. last else {
111- // Decoding an array of scalars from rows: pick the first column
112- return ColumnDecoder < R > ( row: row, columnIndex: 0 , codingPath: codingPath)
111+ // Not yet sure what we are decoding, this will be decided in the SingleValueDecodingContainer functions.
112+ // For decoding an array of scalars (in case of prefetched rows) we pick the first column.
113+ return SingleValueRowDecoder (
114+ columnDecoder: ColumnDecoder < R > ( row: row, columnIndex: 0 , codingPath: codingPath) ,
115+ columnDecodingStrategy: columnDecodingStrategy
116+ )
113117 }
114118 guard let index = row. index ( forColumn: key. stringValue) else {
115119 // Don't use DecodingError.keyNotFound:
@@ -346,7 +350,7 @@ private struct _RowDecoder<R: FetchableRecord>: Decoder {
346350
347351 // Unknown key
348352 //
349- // Should be throw an error? Well... The use case is the following:
353+ // Should we throw an error? Well... The use case is the following:
350354 //
351355 // // SELECT book.*, author.* FROM book
352356 // // JOIN author ON author.id = book.authorId
@@ -487,6 +491,46 @@ private struct _RowDecoder<R: FetchableRecord>: Decoder {
487491 }
488492}
489493
494+ private struct SingleValueRowDecoder < R: FetchableRecord > : SingleValueDecodingContainer {
495+ var columnDecoder : ColumnDecoder < R >
496+ var columnDecodingStrategy : DatabaseColumnDecodingStrategy
497+ let codingPath : [ any CodingKey ] = [ ]
498+
499+ func decodeNil( ) -> Bool { columnDecoder. decodeNil ( ) }
500+ func decode( _ type: Bool . Type ) throws -> Bool { try columnDecoder. decode ( type) }
501+ func decode( _ type: String . Type ) throws -> String { try columnDecoder. decode ( type) }
502+ func decode( _ type: Double . Type ) throws -> Double { try columnDecoder. decode ( type) }
503+ func decode( _ type: Float . Type ) throws -> Float { try columnDecoder. decode ( type) }
504+ func decode( _ type: Int . Type ) throws -> Int { try columnDecoder. decode ( type) }
505+ func decode( _ type: Int8 . Type ) throws -> Int8 { try columnDecoder. decode ( type) }
506+ func decode( _ type: Int16 . Type ) throws -> Int16 { try columnDecoder. decode ( type) }
507+ func decode( _ type: Int32 . Type ) throws -> Int32 { try columnDecoder. decode ( type) }
508+ func decode( _ type: Int64 . Type ) throws -> Int64 { try columnDecoder. decode ( type) }
509+ @available ( macOS 15 . 0 , iOS 18 . 0 , watchOS 11 . 0 , tvOS 18 . 0 , visionOS 2 . 0 , * )
510+ func decode( _ type: Int128 . Type ) throws -> Int128 { try columnDecoder. decode ( type) }
511+ func decode( _ type: UInt . Type ) throws -> UInt { try columnDecoder. decode ( type) }
512+ func decode( _ type: UInt8 . Type ) throws -> UInt8 { try columnDecoder. decode ( type) }
513+ func decode( _ type: UInt16 . Type ) throws -> UInt16 { try columnDecoder. decode ( type) }
514+ func decode( _ type: UInt32 . Type ) throws -> UInt32 { try columnDecoder. decode ( type) }
515+ func decode( _ type: UInt64 . Type ) throws -> UInt64 { try columnDecoder. decode ( type) }
516+ @available ( macOS 15 . 0 , iOS 18 . 0 , watchOS 11 . 0 , tvOS 18 . 0 , visionOS 2 . 0 , * )
517+ func decode( _ type: UInt128 . Type ) throws -> UInt128 { try columnDecoder. decode ( type) }
518+
519+ func decode< T> ( _ type: T . Type ) throws -> T where T: Decodable {
520+ if let type = T . self as? any FetchableRecord . Type {
521+ // Prefer FetchableRecord decoding over Decodable.
522+ return try type. init ( row: columnDecoder. row) as! T
523+ } else {
524+ let decoder = _RowDecoder < R > (
525+ row: columnDecoder. row,
526+ codingPath: [ ] ,
527+ columnDecodingStrategy: columnDecodingStrategy
528+ )
529+ return try T ( from: decoder)
530+ }
531+ }
532+ }
533+
490534// MARK: - PrefetchedRowsDecoder
491535
492536private struct PrefetchedRowsDecoder < R: FetchableRecord > : Decoder {
0 commit comments