line / kotlin-jdsl

Kotlin library that makes it easy to build and execute queries without generated metamodel
https://kotlin-jdsl.gitbook.io/docs/
Apache License 2.0
686 stars 85 forks source link

Empty OR predicate renders '0 = 1' instead of documented '1 = 1' #571

Closed vladimirfx closed 7 months ago

vladimirfx commented 8 months ago

See JpqlOrSerializer.kt:22

shouwn commented 8 months ago

Hi vladimirfx. Thank you for looking at the documentation.

I confused you by using the wrong vocabulary because I'm not a native English speaker.

If all Predicate passed to and() and or() is null or empty, and() will be interpreted as 1 = 1 and or() will be interpreted as 0 = 1.

I wanted to write that in the case of OR, it would render as 0 = 1. Do you have any suggestions on how to modify the above text to make it easier to understand?

vladimirfx commented 8 months ago

Why empty OR is rendered as false? OR is by definition more permissive composition than AND. But for empty predicates is becoming false. Very frustrating. I think code should be corrected, not the documentation.

shouwn commented 8 months ago

The reason Kotlin JDSL renders AND as 1 = 1 and OR as 1 = 0 is because we adopted the concept from Kotlin and the Criteria API.

In the case of AND, I found that the concept of "Vacuous truth" is implemented, but I don't know what concept is adopted in the case of OR.

vladimirfx commented 8 months ago

In this case, there is NO active condition. Current implementation leads to 100% empty query results - It is logically absurd. The user must check all its OR null conditions before giving it to DSL.

shouwn commented 8 months ago

I think an empty query result is sometimes good and sometimes bad depending on the use case. For example, it can be good for delete queries. You can write code to not delete anything if there is no condition.

I don't think this is something that can be generally determined.

Kotlin JDSL is based on Kotlin and JPA. Therefore, I think it would be better to make it follow Kotlin's and JPA's conventions to avoid confusing users.

If you want the OR to be true, I can provide a conjunction and disjunction function in DSL. This allows you to define your own functions, such as fun orElseConjunction(), that combine or() and conjunction().

vladimirfx commented 8 months ago

So, fixing the documentation.

shouwn commented 8 months ago

If all Predicate passed to and() and or() is null or empty, and() will be interpreted as 1 = 1 and or() will be interpreted as 0 = 1.

So, how do I fix it?

vladimirfx commented 8 months ago

Fix documentation, I think:

com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt:1911

But behavior is very annoying - empty predicate id FALSE. I understand that such behavior is in sync with CriteriaBuilder.or but it ruins my intuition ))

Thank you!

shouwn commented 7 months ago

Oh, you meant Kotlin Doc, this is my fault. I'll deploy this as a hotfix.