Merge pull request #2511 from FOCONIS/unselect-lobs

Unselect LOBs when making a distinct select
This commit is contained in:
Rob Bygrave authored and GitHub committed 2022-01-29 15:25:00 +13:00
commit 75a27fa2d6
8 files changed
+122 -12

No files matched your search

@@ -1160,7 +1160,26 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
public boolean isLob() {
return lob;
}
/**
* Returns true if this <code>isLob()</code> or the type will effectively map to a lob.
*/
public boolean isDbLob() {
if (lob) {
return true;
}
switch (dbType) {
case DbPlatformType.JSON:
case DbPlatformType.JSONB:
return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup
case DbPlatformType.JSONBlob:
case DbPlatformType.JSONClob:
return true;
default:
return false;
}
}
public static boolean isLobType(int type) {
switch (type) {
case Types.CLOB:
@@ -62,4 +62,9 @@ class DynamicPropertyAggregationFormula extends DynamicPropertyBase {
ctx.appendParseSelect(parsedFormula, alias);
}
@Override
public boolean isDbLob() {
return false;
}
}
@@ -760,6 +760,10 @@ final class CQueryBuilder {
return dbPlatform.isPlatform(Platform.POSTGRES);
}
boolean isPlatformDistinctNoLobs() {
return dbPlatform.isPlatform(Platform.DB2); // CHECKME: Also oracle?
}
/**
* Return the 'for update' FROM hint (sql server).
*/
@@ -28,6 +28,11 @@ public interface STreeProperty extends ScalarDataReader<Object> {
* Return true if the property is the Id.
*/
boolean isId();
/**
* Returns true, if this is a lob property from db-perspective.
*/
boolean isDbLob();
/**
* Return true if the property is an embedded type.
@@ -53,6 +53,7 @@ public final class SqlTreeBuilder {
private final SpiQuery.TemporalMode temporalMode;
private SqlTreeNode rootNode;
private boolean sqlDistinct;
private final boolean distinctNoLobs;
/**
* Construct for RawSql query.
@@ -65,6 +66,7 @@ public final class SqlTreeBuilder {
this.query = null;
this.subQuery = false;
this.distinctOnPlatform = false;
this.distinctNoLobs = false;
this.queryDetail = queryDetail;
this.predicates = predicates;
this.temporalMode = SpiQuery.TemporalMode.CURRENT;
@@ -97,6 +99,7 @@ public final class SqlTreeBuilder {
this.predicates = predicates;
this.alias = new SqlTreeAlias(request.baseTableAlias(), temporalMode);
this.distinctOnPlatform = builder.isPlatformDistinctOn();
this.distinctNoLobs = builder.isPlatformDistinctNoLobs();
String fromForUpdate = builder.fromForUpdate(query);
CQueryHistorySupport historySupport = builder.getHistorySupport(query);
CQueryDraftSupport draftSupport = builder.getDraftSupport(query);
@@ -266,6 +269,9 @@ public final class SqlTreeBuilder {
if (joinList != null) {
joinList.add(selectNode);
}
if (sqlDistinct && distinctNoLobs) {
selectNode.unselectLobs();
}
return selectNode;
}
@@ -78,4 +78,10 @@ interface SqlTreeNode {
* Create the loader for this node.
*/
SqlTreeLoad createLoad();
/**
* Unselect lobs (for distinct queries on DB2 and Oracle).
*/
default void unselectLobs() {
};
}
@@ -26,8 +26,8 @@ class SqlTreeNodeBean implements SqlTreeNode {
/**
* Set to true if this is a partial object fetch.
*/
final boolean partialObject;
final STreeProperty[] properties;
boolean partialObject;
STreeProperty[] properties;
/**
* Extra where clause added by Where annotation on associated many.
*/
@@ -399,4 +399,33 @@ class SqlTreeNodeBean implements SqlTreeNode {
}
return false;
}
@Override
public void unselectLobs() {
if (children != null) {
for (SqlTreeNode child : children) {
child.unselectLobs();
}
}
if (hasLob()) {
List<STreeProperty> lst = new ArrayList<>();
for (STreeProperty prop : properties) {
if (!prop.isDbLob()) {
lst.add(prop);
}
}
properties = lst.toArray(new STreeProperty[0]);
partialObject = true;
}
}
private boolean hasLob() {
for (STreeProperty prop : properties) {
if (prop.isDbLob()) {
return true;
}
}
return false;
}
}