Reputation: 23
Domain.where {
1 == 0
}.count()
This returned all the elements of the domain class. The more general case:
Domain.where {
false
}.count()
Will return all elements; if I use one of the fields and make a false condition, the result is as expected.
My question is why does this happen (the first case) ? If it is a too naive question, please just suggest some reading material. Thanks!
The version of grails that I use is 2.3.6 (it may be different in newer versions?)
Upvotes: 1
Views: 404
Reputation: 9885
To illustrate Deigote's explanation, here's a very crude implementation of a WHERE query builder (actually just the WHERE clause) using the criteria criteria format:
class WhereBuilder {
def conditions = []
def eq(column, value) {
conditions << [
column: column,
operator: '=',
value: value]
}
def ne(column, value) {
conditions << [
column: column,
operator: '!=',
value: value]
}
String toString() {
'WHERE ' <<
conditions.collect {
"${it.column} ${it.operator} '${it.value}'"
}.join(' AND ')
}
}
def builder = new WhereBuilder()
builder.with {
1 == 0
false
eq 'firstName', 'John'
ne 'lastName', 'Smith'
}
assert builder.toString() == "WHERE firstName = 'John' AND lastName != 'Smith'"
As you can see, the expressions 1 == 0 and false have no effect.
Upvotes: 0
Reputation: 1761
I'm not sure what you are trying to achieve, but here is an explanation (maybe a bit general because of that :).
What you pass to the where
method is actually a DSL for specifying SQL criterias, it just uses normal Groovy syntax to pretend to be more natural. But when you do someProperty != 5 && someOtherProperty == 6
that is not evaluated directly, but transformed to end up in an SQL query as select * from Domain where some_property != 5 and some_other_property = 6
.
Since you are not passing any reference to a property in your criteria (1 == 0
), it gets ignored by the detached criteria DSL evaluator, thus returning the result of select * from domain
. You can try to do for example id != id
to see how you get an empty list as the result. If you again examine the resulting query, you'll see that a where id<>id
is included.
You can learn more about the where
method: https://grails.github.io/grails-doc/latest/guide/GORM.html#whereQueries
Bear in mind that what you pass to the where
method is a Closure
, so the code inside is not executed upfront, and is not necessarily evaluated in the context where it was declared. You can learn more about Groovy Closures. Also about creating DSLs with Groovy, though is a bit of an advanced topic.
(I simplified the SQL queries to make them more undestandable, if you activate the query log of Hibernate or MySQL/other DB you are using, you'll see they are bigger).
Upvotes: 3