 
 public extension Query where DS : Table {
     public func filter(_ f: (DS)->Predicate) -> QueryImpl<DS> {
-        return QueryImpl(connection: connection, dataset: dataset, predicate: f(dataset) && predicate, order: order)
+        return QueryImpl(dataset: dataset, predicate: f(dataset) && predicate, order: order)
     }
 }
 
 public extension Query where DS : JoinProtocol, DS.Left : Table {
     public func filter(_ f: (DS.Left, DS.Right)->Predicate) -> QueryImpl<DS> {
-        return QueryImpl(connection: connection, dataset: dataset, predicate: (dataset.datasets |> f) && predicate, order: order)
+        return QueryImpl(dataset: dataset, predicate: (dataset.datasets |> f) && predicate, order: order)
     }
 }
 

}

public extension Query {
    private func render(dialect:Dialect? = nil) throws -> SQL {
        guard let dialect = dialect.or(else: (connection as? DialectRich).map({$0.dialect})) else {
            throw RDBCFrameworkError.noDialect
        }
        
        return dialect.render(dataset: dataset, filter: self.predicate)
    }
    
    public func execute(dialect:Dialect? = nil) -> Future<ResultSet?> {
        let connection = self.connection
        
        return future(context: immediate) {
            try self.render(dialect: dialect)
        }.flatMap { sql in
            connection.execute(sql: sql)
        }
    }
}

public struct QueryImpl<DS : Dataset> : Query {
    public let connection:Connection
    
    public let dataset:DS
    public let predicate:Predicate
    public let order:Any
    
    init(connection:Connection, dataset:DS, predicate:Predicate, order:Any) {
        self.connection = connection
        self.dataset = dataset
        self.predicate = predicate
        self.order = order

//let t1 = pool.select(from: "test1").map{ $0["firstname"] }
//let t2 = pool.select(from: "test2").map("lastname")

let t1 = Q.select(from: "test1")
let t2 = Q.select(from: "test2").zip(with: t1, .on(true))

//pool.select(from: "test1").map {t1 in [t1["firstname"]]}.zip(with: t2, .using(["id"]), type: .left)
// SELECT a.`id`, a.`name` from `test1` as a;

// SELECT a.`firstname`, b.`comment` from `test1` as a INNER JOIN `test2` as b USING('id') WHERE a.`firstname` == "Daniel";

Q.select(from: "test1").zip(with: Q.select(from: "test2")) { t1, t2 in
    t1["id"] == t2["id"]
}.map { t1, t2 in
    [t1["firstname"], t2["comment"]]
}.filter { t1, t2 in
    t1["firstname"] == "Daniel" || t2["comment"] == "Cool"
}.execute(on: pool).flatMap{$0}.flatMap { results in
    results.columns.zip(results.all())
}.onSuccess { (cols, rows) in
    print(cols)
