     }
 }
 
-// MARK: Fetching From SQL
-
-/// Fetch from SQL:
-///
-///     struct Decoder: DatabaseDecoder { ... }
-///     try dbQueue.read { db in
-///         let values = try Decoder.fetchAll(db, "SELECT ...")
-///     }
-extension DatabaseDecoder {
+try dbQueue.read { db in
+    print("> Fetch from request")
+    let request = Base.all()
+    let bases = try request.fetchAll(db)
+    for base in bases {
+        print(base.description)
+    }
+}
+
+//: Types that adopt both FetchableRecord and TableRecord are able to fetch
+//: right from the base type. Let's allow this as well for MyDatabaseDecoder:
+//:
+//:     try dbQueue.read { db in
+//:         try Base.fetchCursor(db) // Cursor of Base
+//:         try Base.fetchAll(db)    // [Base]
+//:         try Base.fetchOne(db)    // Base?
+//:     }
+extension MyDatabaseDecoder where Self: TableRecord {
+    static func fetchCursor(_ db: Database) throws -> MapCursor<RowCursor, DecodedType> {
+        return try all().fetchCursor(db)
+    }
+    
+    static func fetchAll(_ db: Database) throws -> [DecodedType] {
+        return try all().fetchAll(db)
+    }
+    
+    static func fetchOne(_ db: Database) throws -> DecodedType? {
+        return try all().fetchOne(db)
+    }
+}
+
+try dbQueue.read { db in
+    print("> Fetch from base type")
+    let bases = try Base.fetchAll(db)
+    for base in bases {
+        print(base.description)
+    }
+}
+
+//: Finally, you don't have a true GRDB record unless it allows fetching from
+//: raw SQL:
+//:
+//:     try dbQueue.read { db in
+//:         try Base.fetchCursor(db, "SELECT ...") // Cursor of Base
+//:         try Base.fetchAll(db, "SELECT ...")    // [Base]
+//:         try Base.fetchOne(db, "SELECT ...")    // Base?
+//:     }
+extension MyDatabaseDecoder {
     static func fetchCursor(_ db: Database, _ sql: String, arguments: StatementArguments? = nil, adapter: RowAdapter? = nil) throws -> MapCursor<RowCursor, DecodedType> {
         return try fetchCursor(db, SQLRequest<Self>(sql, arguments: arguments, adapter: adapter))
     }

    }
}

// MARK: Fetching From Base Tye

/// Fetch from SQL:
///
///     struct Decoder: DatabaseDecoder { ... }
///     try dbQueue.read { db in
///         let values = try Decoder.fetchAll(db)
///     }
extension DatabaseDecoder where Self: TableRecord {
    static func fetchCursor(_ db: Database) throws -> MapCursor<RowCursor, DecodedType> {
        return try all().fetchCursor(db)
    }
    
    static func fetchAll(_ db: Database) throws -> [DecodedType] {
        return try all().fetchAll(db)
    }
    
    static func fetchOne(_ db: Database) throws -> DecodedType? {
        return try all().fetchOne(db)
    }
}

// =============================================================================

try dbQueue.read { db in
    do {
        print("> Fetch from SQL")
        let bases = try Base.fetchAll(db, "SELECT * FROM base")
        for base in bases {
            print(base.description)
        }
    }
    
    do {
        print("> Fetch from query interface request")
        let bases = try Base.filter(Column("type") == "Foo").fetchAll(db)
        for base in bases {
            print(base.description)
        }
    }
    
    do {
        print("> Fetch right from the Base type")
        let bases = try Base.fetchAll(db)
        for base in bases {
            print(base.description)
        }
    }
}

//: The resulting code is not as streamlined as usual GRDB code, but we could
//: already do what we needed without much effort.
//:
//: ## Custom Protocol: MyDatabaseDecoder
//:
//: In the rest of this playground, we will define a **new realm of requests**.
//:
//: GRDB ships with three build-in realms of requests: requests of raw rows,
