Question

I'm using Slick versian 2.0.0-M3. If I have two Querys representing relations of the same type, I see there is a union operator to inclusively disjoin them, but I don't see a comparable operator for obtaining their intersection nor their difference. Do such operators not exist in Slick?

I think the foregoing explains what I'm looking for, but if not, here's an example. I have the suppliers table:

case class Supplier(snum: String, sname: String, status: Int, city: String)

class Suppliers(tag: Tag) extends Table[Supplier](tag, "suppliers") {
  def snum  = column[String]("snum")
  def sname = column[String]("sname")
  def status   = column[Int]("status")
  def city     = column[String]("city")
  def * = (snum, sname, status, city) <> (Supplier.tupled, Supplier.unapply _)
}
val suppliers = TableQuery[Suppliers]

If I want to know about suppliers that either are in a particular city or have a particular status, I see how to use Query.union for that:

scala> val thirtySuppliers = suppliers.filter(_.status === 30)
thirtySuppliers: scala.slick.lifted.Query[Suppliers,Suppliers#TableElementType] = scala.slick.lifted.WrappingQuery@166f63a

scala> val londonSuppliers = suppliers.filter(_.city === "London")
londonSuppliers: scala.slick.lifted.Query[Suppliers,Suppliers#TableElementType] = scala.slick.lifted.WrappingQuery@1bea855

scala> (thirtySuppliers union londonSuppliers).foreach(println)
Supplier(S1,Smith,20,London)
Supplier(S4,Clark,20,London)
Supplier(S3,Blake,30,Paris)
Supplier(S5,Adams,30,Athens)

No problem. But what if I want only the suppliers that are both in a particular city and have a particular status? Seems as if I ought to be able to do something like:

(thirtySuppliers intersect londonSuppliers).foreach(println)

Or if I want the suppliers in a particular city except the ones that have a particular status. Can I not do something like:

(thirtySuppliers except londonSuppliers).foreach(println)

SQL has UNION, INTERSECT, and EXCEPT operations, and Slick's Query class has a union method that builds an SQL query using SQL's UNION, but I'm not seeing Query methods in Slick for deriving intersections nor differences. Am I missing them?

Was it helpful?

Solution

There is a pull request that implements this. It will likely make it into 2.0 or 2.1. https://github.com/slick/slick/pull/242 We still need to figure out some details and clean up a bit.

OTHER TIPS

The operations are pretty much composable in that an intersect can just be two filters. For instance

val intersect = suppliers.filter(_.status === 30).filter(_.city === "London")

or except:

val except= suppliers.filter(_.city === "London").filterNot(_.status === 30)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top