PL-8115 CollectionDatasource.getCount() doesn't work correct with DISTINCT

This commit is contained in:
Andrey Subbotin 2016-11-08 16:43:20 +04:00
parent 9e8ef1de86
commit 06cdbde496
3 changed files with 79 additions and 4 deletions

View File

@ -134,6 +134,58 @@ public class QueryTransformerRegexTest extends TestCase {
"select count(h) from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0",
res);
transformer = new QueryTransformerRegex(
"select h.group from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0 order by c.level");
transformer.replaceWithCount();
res = transformer.getResult();
assertEquals(
"select count(h.group) from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0",
res);
transformer = new QueryTransformerRegex(
"select distinct h.group from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0 order by c.level");
transformer.replaceWithCount();
res = transformer.getResult();
assertEquals(
"select count(distinct h.group) from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0",
res);
}
public void testReplaceWithSelectId() {
QueryTransformerRegex transformer = new QueryTransformerRegex(
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0 order by c.level");
transformer.replaceWithSelectId();
String res = transformer.getResult();
assertEquals(
"select h.id from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0",
res);
transformer = new QueryTransformerRegex(
"select h.group from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0 order by c.level");
transformer.replaceWithSelectId();
res = transformer.getResult();
assertEquals(
"select h.group.id from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0",
res);
transformer = new QueryTransformerRegex(
"select distinct h.group from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0 order by c.level");
transformer.replaceWithSelectId();
res = transformer.getResult();
assertEquals(
"select distinct h.group.id from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0",
res);
}
public void testOrderBy() {
@ -152,8 +204,6 @@ public class QueryTransformerRegexTest extends TestCase {
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level having c.level > 0 order by h.group desc",
res);
}
public void testOrderByAscDesc() {

View File

@ -33,6 +33,9 @@ public class QueryParserRegex implements QueryParser {
public static final Pattern QUERY_START_PATTERN = Pattern.compile(QUERY_START_PATTERN_REGEX, Pattern.CASE_INSENSITIVE);
public static final int QS_ALIAS = 2;
public static final String ENTITY_PATH_PATTERN_REGEX = "select(\\s+distinct)?\\s+(%s[\\.]*[a-z0-9]*)?\\s+\\b";
public static final int ENTITY_PATH_ALIAS = 2;
public static final String ENTITY_PATTERN_REGEX = "(\\b[_A-Za-z]+\\$[A-Z][_A-Za-z0-9]*)(\\s+as\\b)?\\s+([a-z]+[a-z0-9]*)*\\b";
public static final Pattern ENTITY_PATTERN = Pattern.compile(ENTITY_PATTERN_REGEX, Pattern.CASE_INSENSITIVE);
public static final int EP_ALIAS = 3;

View File

@ -226,11 +226,22 @@ public class QueryTransformerRegex extends QueryParserRegex implements QueryTran
public void replaceWithCount() {
Matcher entityMatcher = FROM_ENTITY_PATTERN.matcher(buffer);
String alias = findAlias(entityMatcher);
String entityPath = alias;
Matcher entityPathMatcher = Pattern.compile(String.format(ENTITY_PATH_PATTERN_REGEX, alias))
.matcher(buffer);
if (entityPathMatcher.find()) {
String group = entityPathMatcher.group(ENTITY_PATH_ALIAS);
if (group != null && group.startsWith(alias)) {
entityPath = group;
}
}
Matcher distinctMatcher = DISTINCT_PATTERN.matcher(buffer);
buffer.replace(0, entityMatcher.start(),
"select count(" + (distinctMatcher.find() ? "distinct " : "") + alias + ") ");
"select count(" + (distinctMatcher.find() ? "distinct " : "") + entityPath + ") ");
Matcher orderMatcher = ORDER_BY_PATTERN.matcher(buffer);
if (orderMatcher.find()) {
@ -247,11 +258,22 @@ public class QueryTransformerRegex extends QueryParserRegex implements QueryTran
public void replaceWithSelectId(String pkName) {
Matcher entityMatcher = FROM_ENTITY_PATTERN.matcher(buffer);
String alias = findAlias(entityMatcher);
String entityPath = alias;
Matcher entityPathMatcher = Pattern.compile(String.format(ENTITY_PATH_PATTERN_REGEX, alias))
.matcher(buffer);
if (entityPathMatcher.find()) {
String group = entityPathMatcher.group(ENTITY_PATH_ALIAS);
if (group != null && group.startsWith(alias)) {
entityPath = group;
}
}
Matcher distinctMatcher = DISTINCT_PATTERN.matcher(buffer);
buffer.replace(0, entityMatcher.start(),
"select " + (distinctMatcher.find() ? "distinct " : "") + alias + "." + pkName);
"select " + (distinctMatcher.find() ? "distinct " : "") + entityPath + "." + pkName + " ");
Matcher orderMatcher = ORDER_BY_PATTERN.matcher(buffer);
if (orderMatcher.find()) {