         if let type = T.self as? DatabaseValueConvertible.Type {
             // Prefer DatabaseValueConvertible decoding over Decodable.
             // This allows decoding Date from String, or DatabaseValue from NULL.
+            // TODO: switch to more efficient decoding apis
             return type.decode(from: row[column.stringValue], conversionContext: ValueConversionContext(row).atColumn(column.stringValue)) as! T
         } else {
-            return try T(from: RowDecoder(row: row, codingPath: [column]))
+            return try T(from: RowSingleValueDecoder(row: row, codingPath: [column]))
         }
     }
 }

    }
    
    func singleValueContainer() throws -> SingleValueDecodingContainer {
        // Asked for a value type: column name required
        guard let codingKey = codingPath.last else {
            throw DecodingError.typeMismatch(
                RowDecoder.self,
                DecodingError.Context(codingPath: codingPath, debugDescription: "single value decoding requires a coding key"))
        }
        return RowSingleValueDecodingContainer(row: row, codingPath: codingPath, column: codingKey)
    }
}


                return type.decode(from: row, atUncheckedIndex: index) as! T
            } else {
                do {
                    // This decoding will fail for types that decode from keyed
                    // or unkeyed containers, because we're decoding a single
                    // value here (string, int, double, data, null). If such an
                    // error happens, we'll switch to JSON decoding.
                    return try T(from: RowSingleValueDecoder(row: row, codingPath: codingPath + [key]))
                } catch let error as DecodingError {
                    if case .typeMismatch(_, let context) = error,
                        context.debugDescription == "keyed decoding is not supported" || context.debugDescription == "unkeyed decoding is not supported",
                        let data = row.dataNoCopy(atIndex: index)
                    {
                        return try JSONDecoder().decode(type.self, from: data)
                    } else {
                        throw error
                    }
                }
            }
