Why it does not work
As cvot noted in his comment , the reason for this does not work, because:
Slick translates None as SQL NULL, including SQL NULL with 3-digit logical code, so (None === a) is None, regardless of the value of a ... basically, if there is nothing in the expression. the expression will be None, so the filter expression will be considered false, and the query result will be empty.
However, there is a way to get the same behavior that you want (filtering only if an extra value is provided).
The way to achieve the desired behavior
The main thing to note is that to compile, compile Scala into a combination of calls to map / flatMap / withFilter / filter . Slick, if I understand correctly, works with the resulting structure when it compiles the understanding of Scala into an SQL query.
This allows us to create a query in parts:
val baseQuery = for { u <- users if u.companyId === companyId } yield u val possiblyFilteredByLocation = if (locationId.isDefined) { baseQuery.withFilter(u => u.locationId === locationId.get } else baseQuery val possiblyFilteredBySalaryAndOrLocation = if (salary.isDefined) { possiblyFilteredByLocation.withFilter(u => u.salary >= salary.get) } else possiblyFilteredByLocation possiblyFilteredBySalaryAndOrLocation.list()
We can simplify this by using var and fold :
var query = for { u <- users if u.companyId === companyId } yield u query = locationId.fold(query)(id => query.withFilter(u => u.locationId === id)) query = salary.fold(query)(salary => query.withFilter(u => u.salary >= salary)) query.list()
If we do this often, we can generalize this filtering pattern to Option to something like this:
// Untested, probably does not compile implicit class ConditionalFilter(query: Query) { def ifPresent[T](value: Option[T], predicate: (Query, T) => Query) = { value.fold(query)(predicate(query, _)) } }
Then we can simplify the entire filter chain to:
query .ifPresent[Int](locationId, (q, id) => q.withFilter(u => u.locationId === id)) .ifPresent[Int](salary, (q, s) => q.withFilter(u => u.salary >= s)) .list()