From 38a35b96a74f0ea5753e5492685727983624b600 Mon Sep 17 00:00:00 2001 From: Luigi Dell'Aquila Date: Tue, 27 Nov 2018 09:43:53 +0100 Subject: [PATCH] Fix SQL CONTAINS with lists of lists Resolves: #8653 --- .../core/sql/parser/OContainsCondition.java | 21 +++++++--- .../OSelectStatementExecutionTest.java | 39 +++++++++++++++++++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/parser/OContainsCondition.java b/core/src/main/java/com/orientechnologies/orient/core/sql/parser/OContainsCondition.java index 410b077beb8..5201589e207 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/parser/OContainsCondition.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/parser/OContainsCondition.java @@ -35,16 +35,27 @@ public Object jjtAccept(OrientSqlVisitor visitor, Object data) { public boolean execute(Object left, Object right) { if (left instanceof Collection) { if (right instanceof Collection) { - if (((Collection) left).containsAll((Collection) right)) { - return true; - } - if (((Collection) right).size() == 1) { Object item = ((Collection) right).iterator().next(); if (item instanceof OResult && ((OResult) item).getPropertyNames().size() == 1) { Object propValue = ((OResult) item).getProperty(((OResult) item).getPropertyNames().iterator().next()); - return ((Collection) left).contains(propValue); + if (((Collection) left).contains(propValue)) { + return true; + } + } + if (((Collection) left).contains(item)) { + return true; + } + if (item instanceof OResult) { + item = ((OResult) item).getElement().orElse(null); } + if (item instanceof OIdentifiable && ((Collection) left).contains(item)) { + return true; + } + } + + if (OMultiValue.contains(left, right)) { + return true; } return false; } diff --git a/core/src/test/java/com/orientechnologies/orient/core/sql/executor/OSelectStatementExecutionTest.java b/core/src/test/java/com/orientechnologies/orient/core/sql/executor/OSelectStatementExecutionTest.java index 51fb7b9d92e..fe372a81954 100644 --- a/core/src/test/java/com/orientechnologies/orient/core/sql/executor/OSelectStatementExecutionTest.java +++ b/core/src/test/java/com/orientechnologies/orient/core/sql/executor/OSelectStatementExecutionTest.java @@ -3851,4 +3851,43 @@ public void testOrderByWithCollate() { } } + @Test + public void testContainsEmptyCollection() { + String className = "testContainsEmptyCollection"; + + db.createClassIfNotExist(className); + + db.command("INSERT INTO " + className + " content {\"name\": \"jack\", \"age\": 22}").close(); + db.command("INSERT INTO " + className + " content {\"name\": \"rose\", \"age\": 22, \"test\": [[]]}").close(); + db.command("INSERT INTO " + className + " content {\"name\": \"rose\", \"age\": 22, \"test\": [[1]]}").close(); + db.command("INSERT INTO " + className + " content {\"name\": \"pete\", \"age\": 22, \"test\": [{}]}").close(); + db.command("INSERT INTO " + className + " content {\"name\": \"david\", \"age\": 22, \"test\": [\"hello\"]}").close(); + + try (OResultSet result = db.query("select from " + className + " where test contains []")) { + Assert.assertTrue(result.hasNext()); + result.next(); + Assert.assertFalse(result.hasNext()); + } + } + + + @Test + public void testContainsCollection() { + String className = "testContainsCollection"; + + db.createClassIfNotExist(className); + + db.command("INSERT INTO " + className + " content {\"name\": \"jack\", \"age\": 22}").close(); + db.command("INSERT INTO " + className + " content {\"name\": \"rose\", \"age\": 22, \"test\": [[]]}").close(); + db.command("INSERT INTO " + className + " content {\"name\": \"rose\", \"age\": 22, \"test\": [[1]]}").close(); + db.command("INSERT INTO " + className + " content {\"name\": \"pete\", \"age\": 22, \"test\": [{}]}").close(); + db.command("INSERT INTO " + className + " content {\"name\": \"david\", \"age\": 22, \"test\": [\"hello\"]}").close(); + + try (OResultSet result = db.query("select from " + className + " where test contains [1]")) { + Assert.assertTrue(result.hasNext()); + result.next(); + Assert.assertFalse(result.hasNext()); + } + } + }