Why does 'xxx is null' is generated in where condition when no null is actually compared?

21 views
Skip to first unread message

Teck Hooi Lim

unread,
Apr 22, 2016, 4:06:00 AM4/22/16
to Slick / ScalaQuery
I wanted to create a Slick query similar to this SQL,

select lots.oid, lots.cat from lots
    left join bks on (lots.cat = bks.cat and bks.oid=100)
 where not exists (select 1 from bks_dates bd where
     lots.oid=bd.lots_oid and bd.bk_oid = bks.oid) and lots.e_oid=bk.e_oid

using,

val elQuery = slickEls
  .joinLeft(slickBks)
  .on((el, bk) => el.cat === bk.cat && bk.oid === bookingsOid && bk.etsOid === el.etsOid)
  .filter(x => x._2.map(_.etsOid === x._1.etsOid))

val finalQuery = for {
  a <- elQuery if !(slickBds.filter(bd => a._2.map(_.oid === bd.bksOid).isEmpty && a._1.oid === bd.elOid).exists)
} yield a

finalQuery.result.statements.foreach(x => println(s"xx => $x"))

What was printed was this,

select x2.`oid`, x2.`ets_oid`, x2.`cat`, x3.`ets_oid`, x3.`oid`, x3.`el_oid`, x3.`amount`, x3.`extras`, x3.`cat` from `lots` x2 
  left outer join `bks` x3 on ((x2.`cat` = x3.`cat`) and (x3.`oid` = 100)) 
    and (x3.`ets_oid` = x2.`ets_oid`) 
where (case when (x3.`ets_oid` is not null) then (x3.`ets_oid` = x2.`ets_oid`) else null end) 
and (not exists(select `bks_oid`, `oid`, `taken`, `el_oid`, `r_date`, `ets_oid` from `bk_dates` 
  where (x3.`ets_oid` is null) and (x2.`oid` = `el_oid`)))

Where did x3.`ets_oid` is null come from? How I do to fix a._2.map(_.oid === bd.bksOid).isEmpty to reflect the 
condition bd.bk_oid = bks.oid I wanted ? I have a feeling isEmpty is responsible for it. Thanks


Other supporting information for reference,

trait ForIssueDefinitions {

// import driver.api._ // required but a Slick environment needed to be setup

case class DBBk(oid: Option[Long],
elOid: Option[Long],
etsOid: Long,
amount: Float,
extras: Option[String],
cat: Option[String])

class Bks(tag: Tag) extends Table[DBBk](tag, "bks") {
def oid = column[Option[Long]]("oid", O.AutoInc, O.PrimaryKey)
def elOid = column[Option[Long]]("el_oid")
def etsOid = column[Long]("ets_oid")
def amount = column[Float]("amount")
def extras = column[Option[String]]("extras")
def cat = column[Option[String]]("cat")
def * = (oid, elOid, etsOid, amount, extras, cat) <> ((DBBk.apply _).tupled, DBBk.unapply)
}

case class DBLot(oid: Option[Long],
etsOid: Long,
cat: Option[String])

class Els(tag: Tag) extends Table[DBLot](tag, "lots") {
def oid = column[Option[Long]]("oid", O.AutoInc, O.PrimaryKey)
def etsOid = column[Long]("ets_oid")
def cat = column[Option[String]]("cat")
def * = (oid, etsOid, cat) <> ((DBLot.apply _).tupled, DBLot.unapply)
}

case class DBBd(oid: Option[Long],
bksOid: Long,
rDate: LocalDate,
taken: Boolean,
elOid: Option[Long],
etsOid: Long
)

class Bds(tag: Tag) extends Table[DBBd](tag, "bk_dates") {
def oid = column[Option[Long]]("oid", O.AutoInc, O.PrimaryKey)
def bksOid = column[Long]("bks_oid")
def rDate = column[LocalDate]("r_date")
def taken = column[Boolean]("taken")
def elOid = column[Option[Long]]("el_oid")
def etsOid = column[Long]("ets_oid")
def * = (oid, bksOid, rDate, taken, elOid, etsOid) <> ((DBBd.apply _).tupled, DBBd.unapply)
}

val slickBds = TableQuery[Bds]
val slickEls = TableQuery[Els]
val slickBks = TableQuery[Bks]
}
Reply all
Reply to author
Forward
0 new messages