You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2018/12/20 22:52:35 UTC
[syncope] 01/02: [SYNCOPE-1419] provides the correct behavior in
case of multivalue fields
This is an automated email from the ASF dual-hosted git repository.
fmartelli pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
commit 6a8165568da35a39295b521958ce211e2ac2f219
Author: fmartelli <fa...@gmail.com>
AuthorDate: Thu Dec 20 15:19:16 2018 +0100
[SYNCOPE-1419] provides the correct behavior in case of multivalue fields
---
.../core/persistence/jpa/dao/JPAAnySearchDAO.java | 209 +++++++++++----------
.../core/persistence/jpa/inner/AnySearchTest.java | 14 ++
2 files changed, 128 insertions(+), 95 deletions(-)
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index da76f48..26eccfd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -834,111 +834,126 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
final boolean not,
final List<Object> parameters,
final SearchSupport svs) {
+ // This first branch is required for handling with not conditions given on multivalue fields (SYNCOPE-1419)
+ if (not && !(cond instanceof AnyCond)
+ && schema.isMultivalue()
+ && cond.getType() != AttributeCond.Type.ISNULL
+ && cond.getType() != AttributeCond.Type.ISNOTNULL) {
+ query.append("any_id NOT IN (SELECT DISTINCT any_id FROM ");
+ if (schema.isUniqueConstraint()) {
+ query.append(svs.asSearchViewSupport().uniqueAttr().name);
+ } else {
+ query.append(svs.asSearchViewSupport().attr().name);
+ }
+ query.append(" WHERE schema_id='").append(schema.getKey());
+ fillAttrQuery(query, attrValue, schema, cond, false, parameters, svs);
+ query.append(")");
+ } else {
+ // activate ignoreCase only for EQ and LIKE operators
+ boolean ignoreCase = AttributeCond.Type.ILIKE == cond.getType() || AttributeCond.Type.IEQ == cond.getType();
- // activate ignoreCase only for EQ and LIKE operators
- boolean ignoreCase = AttributeCond.Type.ILIKE == cond.getType() || AttributeCond.Type.IEQ == cond.getType();
-
- String column = (cond instanceof AnyCond) ? cond.getSchema() : svs.fieldName(schema.getType());
- if ((schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) && ignoreCase) {
- column = "LOWER (" + column + ")";
- }
- if (!(cond instanceof AnyCond)) {
- column = "' AND " + column;
- }
-
- switch (cond.getType()) {
-
- case ISNULL:
- query.append(column).append(not
- ? " IS NOT NULL"
- : " IS NULL");
- break;
+ String column = (cond instanceof AnyCond) ? cond.getSchema() : svs.fieldName(schema.getType());
+ if ((schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) && ignoreCase) {
+ column = "LOWER (" + column + ")";
+ }
+ if (!(cond instanceof AnyCond)) {
+ column = "' AND " + column;
+ }
- case ISNOTNULL:
- query.append(column).append(not
- ? " IS NULL"
- : " IS NOT NULL");
- break;
+ switch (cond.getType()) {
+
+ case ISNULL:
+ query.append(column).append(not
+ ? " IS NOT NULL"
+ : " IS NULL");
+ break;
+
+ case ISNOTNULL:
+ query.append(column).append(not
+ ? " IS NULL"
+ : " IS NOT NULL");
+ break;
+
+ case ILIKE:
+ case LIKE:
+ if (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) {
+ query.append(column);
+ if (not) {
+ query.append(" NOT ");
+ }
+ query.append(" LIKE ");
+ if (ignoreCase) {
+ query.append("LOWER(?").append(setParameter(parameters, cond.getExpression())).append(')');
+ } else {
+ query.append('?').append(setParameter(parameters, cond.getExpression()));
+ }
+ } else {
+ if (!(cond instanceof AnyCond)) {
+ query.append("' AND");
+ }
+ query.append(" 1=2");
+ LOG.error("LIKE is only compatible with string or enum schemas");
+ }
+ break;
- case ILIKE:
- case LIKE:
- if (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) {
+ case IEQ:
+ case EQ:
query.append(column);
if (not) {
- query.append(" NOT ");
- }
- query.append(" LIKE ");
- if (ignoreCase) {
- query.append("LOWER(?").append(setParameter(parameters, cond.getExpression())).append(')');
+ query.append("<>");
} else {
- query.append('?').append(setParameter(parameters, cond.getExpression()));
+ query.append('=');
}
- } else {
- if (!(cond instanceof AnyCond)) {
- query.append("' AND");
+ if ((schema.getType() == AttrSchemaType.String
+ || schema.getType() == AttrSchemaType.Enum) && ignoreCase) {
+ query.append("LOWER(?").append(setParameter(parameters, attrValue.getValue())).append(')');
+ } else {
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
}
- query.append(" 1=2");
- LOG.error("LIKE is only compatible with string or enum schemas");
- }
- break;
+ break;
- case IEQ:
- case EQ:
- query.append(column);
- if (not) {
- query.append("<>");
- } else {
- query.append('=');
- }
- if ((schema.getType() == AttrSchemaType.String
- || schema.getType() == AttrSchemaType.Enum) && ignoreCase) {
- query.append("LOWER(?").append(setParameter(parameters, attrValue.getValue())).append(')');
- } else {
+ case GE:
+ query.append(column);
+ if (not) {
+ query.append('<');
+ } else {
+ query.append(">=");
+ }
query.append('?').append(setParameter(parameters, attrValue.getValue()));
- }
- break;
-
- case GE:
- query.append(column);
- if (not) {
- query.append('<');
- } else {
- query.append(">=");
- }
- query.append('?').append(setParameter(parameters, attrValue.getValue()));
- break;
+ break;
- case GT:
- query.append(column);
- if (not) {
- query.append("<=");
- } else {
- query.append('>');
- }
- query.append('?').append(setParameter(parameters, attrValue.getValue()));
- break;
+ case GT:
+ query.append(column);
+ if (not) {
+ query.append("<=");
+ } else {
+ query.append('>');
+ }
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
+ break;
- case LE:
- query.append(column);
- if (not) {
- query.append('>');
- } else {
- query.append("<=");
- }
- query.append('?').append(setParameter(parameters, attrValue.getValue()));
- break;
+ case LE:
+ query.append(column);
+ if (not) {
+ query.append('>');
+ } else {
+ query.append("<=");
+ }
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
+ break;
- case LT:
- query.append(column);
- if (not) {
- query.append(">=");
- } else {
- query.append('<');
- }
- query.append('?').append(setParameter(parameters, attrValue.getValue()));
- break;
+ case LT:
+ query.append(column);
+ if (not) {
+ query.append(">=");
+ } else {
+ query.append('<');
+ }
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
+ break;
- default:
+ default:
+ }
}
}
@@ -973,12 +988,16 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
break;
default:
- if (checked.getLeft().isUniqueConstraint()) {
- query.append(svs.asSearchViewSupport().uniqueAttr().name);
+ if (not && checked.getLeft().isMultivalue()) {
+ query.append(svs.field().name).append(" WHERE ");
} else {
- query.append(svs.asSearchViewSupport().attr().name);
+ if (checked.getLeft().isUniqueConstraint()) {
+ query.append(svs.asSearchViewSupport().uniqueAttr().name);
+ } else {
+ query.append(svs.asSearchViewSupport().attr().name);
+ }
+ query.append(" WHERE schema_id='").append(checked.getLeft().getKey());
}
- query.append(" WHERE schema_id='").append(checked.getLeft().getKey());
fillAttrQuery(query, checked.getRight(), checked.getLeft(), cond, not, parameters, svs);
}
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
index 43cc944..8d8ea69 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
@@ -770,4 +770,18 @@ public class AnySearchTest extends AbstractTest {
searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER),
users.size());
}
+
+ @Test
+ public void issueSYNCOPE1419() {
+ AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
+ loginDateCond.setSchema("loginDate");
+ loginDateCond.setExpression("2009-05-26");
+
+ SearchCond cond = SearchCond.getNotLeafCond(loginDateCond);
+ assertTrue(cond.isValid());
+
+ List<User> users = searchDAO.search(cond, AnyTypeKind.USER);
+ assertNotNull(users);
+ assertEquals(4, users.size());
+ }
}