From commits-return-12818-archive-asf-public=cust-asf.ponee.io@syncope.apache.org Fri Dec 21 00:20:44 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 3085618067B for ; Fri, 21 Dec 2018 00:20:44 +0100 (CET) Received: (qmail 22096 invoked by uid 500); 20 Dec 2018 23:20:43 -0000 Mailing-List: contact commits-help@syncope.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@syncope.apache.org Delivered-To: mailing list commits@syncope.apache.org Received: (qmail 22081 invoked by uid 99); 20 Dec 2018 23:20:43 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 20 Dec 2018 23:20:43 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id B058F8528D; Thu, 20 Dec 2018 23:20:42 +0000 (UTC) Date: Thu, 20 Dec 2018 23:20:44 +0000 To: "commits@syncope.apache.org" Subject: [syncope] 02/03: [SYNCOPE-1419] provides the correct behavior in case of multivalue fields MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit From: fmartelli@apache.org In-Reply-To: <154534804258.19391.8243870906700283191@gitbox.apache.org> References: <154534804258.19391.8243870906700283191@gitbox.apache.org> X-Git-Host: gitbox.apache.org X-Git-Repo: syncope X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Rev: f4adfd2fc6e11ac33c556356db4bc066f4895565 X-Git-NotificationType: diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated Message-Id: <20181220232042.B058F8528D@gitbox.apache.org> This is an automated email from the ASF dual-hosted git repository. fmartelli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/syncope.git commit f4adfd2fc6e11ac33c556356db4bc066f4895565 Author: fmartelli 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 | 197 +++++++++++---------- .../core/persistence/jpa/inner/AnySearchTest.java | 14 ++ 2 files changed, 120 insertions(+), 91 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 c669690..84f463e 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 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: + } } } 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 users = searchDAO.search(cond, AnyTypeKind.USER); + assertNotNull(users); + assertEquals(4, users.size()); + } }