title: Slick: dynamic sortBy in a query with left join
body: <p>This is a problem derived from <a href="https://stackoverflow.com/questions/24180017/dynamic-query-parameters-in-slick-sorting/24188487?noredirect=1#comment37342646_24188487">another question</a>. I need to be able to dynamically pass a column to be sorted on in a Slick query which has a left join. The problem in this particular situation is that left joined table becomes optional and I have no idea how to handle that. If I make table <code>Company</code> not optional I'm getting <code>SlickException: Read NULL value for ResultSet column Path</code></p>
  
  <p>Example:</p>
  
  <pre><code>def list(filter: String, orderBy: Int) = {
  
      DB.withDynSession {
  
          val data = for {
              (computer, company) &lt;- Computer.where(_.name like filter) leftJoin
                  Company on (_.companyId === _.id)
          } yield (computer, company.?)
  
          val sortedData = orderBy match {
              case 2 =&gt; data.sortBy(_._1.name) //Works ok, column from a primary table
              case 3 =&gt; data.sortBy(_._2.name) //Error "Cannot resolve symbol name", because table is optional
          }
  
      }
  
  }
  </code></pre>
  
  <p>Slick auto generated table classes used in example above:</p>
  
  <pre><code>package tables
  // AUTO-GENERATED Slick data model
  /** Stand-alone Slick data model for immediate use */
  object Tables extends {
    val profile = scala.slick.driver.H2Driver
  } with Tables
  
  /** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */
  trait Tables {
    val profile: scala.slick.driver.JdbcProfile
    import profile.simple._
    import scala.slick.model.ForeignKeyAction
    // NOTE: GetResult mappers for plain SQL are only generated for tables where Slick knows how to map the types of all columns.
    import scala.slick.jdbc.{GetResult =&gt; GR}
  
    /** DDL for all tables. Call .create to execute. */
    lazy val ddl = Company.ddl ++ Computer.ddl
  
    /** Entity class storing rows of table Company
     *  @param id Database column ID PrimaryKey
     *  @param name Database column NAME  */
    case class CompanyRow(id: Long, name: String)
    /** GetResult implicit for fetching CompanyRow objects using plain SQL queries */
    implicit def GetResultCompanyRow(implicit e0: GR[Long], e1: GR[String]): GR[CompanyRow] = GR{
      prs =&gt; import prs._
      CompanyRow.tupled((&lt;&lt;[Long], &lt;&lt;[String]))
    }
    /** Table description of table COMPANY. Objects of this class serve as prototypes for rows in queries. */
    class Company(tag: Tag) extends Table[CompanyRow](tag, "COMPANY") {
      def * = (id, name) &lt;&gt; (CompanyRow.tupled, CompanyRow.unapply)
      /** Maps whole row to an option. Useful for outer joins. */
      def ? = (id.?, name.?).shaped.&lt;&gt;({r=&gt;import r._; _1.map(_=&gt; CompanyRow.tupled((_1.get, _2.get)))}, (_:Any) =&gt;  throw new Exception("Inserting into ? projection not supported."))
  
      /** Database column ID PrimaryKey */
      val id: Column[Long] = column[Long]("ID", O.PrimaryKey)
      /** Database column NAME  */
      val name: Column[String] = column[String]("NAME")
    }
    /** Collection-like TableQuery object for table Company */
    lazy val Company = new TableQuery(tag =&gt; new Company(tag))
  
    /** Entity class storing rows of table Computer
     *  @param id Database column ID PrimaryKey
     *  @param name Database column NAME 
     *  @param introduced Database column INTRODUCED 
     *  @param discontinued Database column DISCONTINUED 
     *  @param companyId Database column COMPANY_ID  */
    case class ComputerRow(id: Long, name: String, introduced: Option[java.sql.Timestamp], discontinued: Option[java.sql.Timestamp], companyId: Option[Long])
    /** GetResult implicit for fetching ComputerRow objects using plain SQL queries */
    implicit def GetResultComputerRow(implicit e0: GR[Long], e1: GR[String], e2: GR[Option[java.sql.Timestamp]], e3: GR[Option[Long]]): GR[ComputerRow] = GR{
      prs =&gt; import prs._
      ComputerRow.tupled((&lt;&lt;[Long], &lt;&lt;[String], &lt;&lt;?[java.sql.Timestamp], &lt;&lt;?[java.sql.Timestamp], &lt;&lt;?[Long]))
    }
    /** Table description of table COMPUTER. Objects of this class serve as prototypes for rows in queries. */
    class Computer(tag: Tag) extends Table[ComputerRow](tag, "COMPUTER") {
      def * = (id, name, introduced, discontinued, companyId) &lt;&gt; (ComputerRow.tupled, ComputerRow.unapply)
      /** Maps whole row to an option. Useful for outer joins. */
      def ? = (id.?, name.?, introduced, discontinued, companyId).shaped.&lt;&gt;({r=&gt;import r._; _1.map(_=&gt; ComputerRow.tupled((_1.get, _2.get, _3, _4, _5)))}, (_:Any) =&gt;  throw new Exception("Inserting into ? projection not supported."))
  
      /** Database column ID PrimaryKey */
      val id: Column[Long] = column[Long]("ID", O.PrimaryKey)
      /** Database column NAME  */
      val name: Column[String] = column[String]("NAME")
      /** Database column INTRODUCED  */
      val introduced: Column[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("INTRODUCED")
      /** Database column DISCONTINUED  */
      val discontinued: Column[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("DISCONTINUED")
      /** Database column COMPANY_ID  */
      val companyId: Column[Option[Long]] = column[Option[Long]]("COMPANY_ID")
  
      /** Foreign key referencing Company (database name FK_COMPUTER_COMPANY_1) */
      lazy val companyFk = foreignKey("FK_COMPUTER_COMPANY_1", companyId, Company)(r =&gt; r.id, onUpdate=ForeignKeyAction.Restrict, onDelete=ForeignKeyAction.Restrict)
    }
    /** Collection-like TableQuery object for table Computer */
    lazy val Computer = new TableQuery(tag =&gt; new Computer(tag))
  }
  </code></pre>