Skip to content
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

Merged
merged 2 commits into from
Jan 29, 2022

Conversation

rPraml
Copy link
Contributor

@rPraml rPraml commented Jan 27, 2022

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)) or DBMS_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:

  • Ebean unselects the lobs and lazy load is disabled
  • the lob is part of a findSingleAttribute-query and distinct is used.
    In this case you can use select("cast(lobProp as varchar(32000))") or fetch("el.path", "cast(lobProp as varchar(32000))") in your application

This fixes #2495

return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup
case DbPlatformType.JSONBlob:
case DbPlatformType.JSONClob:
return true;
Copy link
Contributor Author

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?

Copy link
Member

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?
Copy link
Contributor Author

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}

Copy link
Member

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());
Copy link
Contributor Author

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() {
Copy link
Contributor Author

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;
Copy link
Member

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.

@rbygrave rbygrave added this to the 12.15.0 milestone Jan 29, 2022
@rbygrave rbygrave merged commit 75a27fa into ebean-orm:master Jan 29, 2022
@rPraml rPraml deleted the unselect-lobs branch January 23, 2023 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DB2: select distinct with lob/clob fields
3 participants