-
-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unselect LOBs when making a distinct select #2511
Conversation
return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup | ||
case DbPlatformType.JSONBlob: | ||
case DbPlatformType.JSONClob: | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we delegate that decision to the DB-platform?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment I think the above is good and that we should not delegate this to the DB-platform. I believe JSON types are generally more "clob" than "varchar" in nature ... it is a little tempting to not even have the dbLength == 0 check.
@@ -760,6 +760,10 @@ boolean isPlatformDistinctOn() { | |||
return dbPlatform.isPlatform(Platform.POSTGRES); | |||
} | |||
|
|||
boolean isPlatformDistinctNoLobs() { | |||
return dbPlatform.isPlatform(Platform.DB2); // CHECKME: Also oracle? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not yet test that in oracle. That may be also delegated to DatabasePlatform
Maybe returning a enum:
enum DistinctMode { NORMAL, DISTINCT_ON, UNSELECT_LOBS}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, tests all passing with Oracle I believe (last local run, odd problems running oracle test via github workflow)
@AfterEach | ||
void cleanup() { | ||
if (bean != null && bean.getId() != null) { | ||
DB.delete(EBasicJsonMap.class, bean.getId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored cleanup a bit
@@ -50,6 +59,36 @@ public void whereManyPredicate() { | |||
assertThat(query2.getGeneratedSql()).contains("select distinct on (t0.id) "); | |||
} | |||
|
|||
@Test | |||
@ForPlatform(Platform.DB2) | |||
public void whereManyPredicateDb2() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, the test is not yet starting on current master branch, because of the maxTableNameLength
and maxConstraintNameLength
of 18 char limits in DB2-platform. (changing them to 128 and the test will run)
We will introduce a Legacy/DB2LUW/... platform as suggested in #2484 soon
return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup | ||
case DbPlatformType.JSONBlob: | ||
case DbPlatformType.JSONClob: | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment I think the above is good and that we should not delegate this to the DB-platform. I believe JSON types are generally more "clob" than "varchar" in nature ... it is a little tempting to not even have the dbLength == 0 check.
Some platforms like DB2, Oracle and also Postgres do not allow to perform a
select distinct
when LOB columns are used.There was a related issue #900 for postgres, but DB2 does not support
select distinct on (id)
Workarounds like
cast(lob_column as varchar(32000))
orDBMS_LOB.substr(lob_column , 32000)
would be not reliable enough. So for these platforms we must not select lobs, when performing a distinct query.Ebean automatically unselect these columns and rely on lazy load of the properties.
Note: There are some edge cases, when that will not work:
In this case you can use
select("cast(lobProp as varchar(32000))")
orfetch("el.path", "cast(lobProp as varchar(32000))")
in your applicationThis fixes #2495