diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAllCondition.java b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAllCondition.java index 1d2afa14c..81f15a2a3 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAllCondition.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAllCondition.java @@ -40,33 +40,31 @@ public ContainsAllCondition(final int id) { public boolean execute(Object left, Object right) { if (left instanceof Collection) { if (right instanceof Collection) - return ((Collection) left).containsAll((Collection) right); + return ((Collection) left).containsAll((Collection) right); if (right instanceof Iterable) - right = ((Iterable) right).iterator(); + right = ((Iterable) right).iterator(); - if (right instanceof Iterator) { - final Iterator iterator = (Iterator) right; + if (right instanceof Iterator iterator) { while (iterator.hasNext()) { final Object next = iterator.next(); - if (!((Collection) left).contains(next)) { + if (!((Collection) left).contains(next)) return false; - } + } } return ((Collection) left).contains(right); } if (left instanceof Iterable) - left = ((Iterable) left).iterator(); + left = ((Iterable) left).iterator(); - if (left instanceof Iterator) { + if (left instanceof Iterator leftIterator) { if (!(right instanceof Iterable)) right = Collections.singleton(right); - right = ((Iterable) right).iterator(); + right = ((Iterable) right).iterator(); - final Iterator leftIterator = (Iterator) left; - final Iterator rightIterator = (Iterator) right; + final Iterator rightIterator = (Iterator) right; while (rightIterator.hasNext()) { final Object leftItem = rightIterator.next(); boolean found = false; diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAnyCondition.java b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAnyCondition.java index 6e402a4b6..3bd5ef696 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAnyCondition.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsAnyCondition.java @@ -40,38 +40,35 @@ public ContainsAnyCondition(final int id) { public boolean execute(Object left, Object right) { if (left instanceof Collection) { - if (right instanceof Iterable) { - right = ((Iterable) right).iterator(); - } - if (right instanceof Iterator) { - final Iterator iterator = (Iterator) right; + if (right instanceof Iterable) + right = ((Iterable) right).iterator(); + + if (right instanceof Iterator iterator) { while (iterator.hasNext()) { final Object next = iterator.next(); - if (((Collection) left).contains(next)) { + if (((Collection) left).contains(next)) return true; - } } } - return false; + return ((Collection) left).contains(right); } - if (left instanceof Iterable) { - left = ((Iterable) left).iterator(); - } - if (left instanceof Iterator) { - if (!(right instanceof Iterable)) { + + if (left instanceof Iterable) + left = ((Iterable) left).iterator(); + + if (left instanceof Iterator leftIterator) { + if (!(right instanceof Iterable)) right = Collections.singleton(right); - } - right = ((Iterable) right).iterator(); - final Iterator leftIterator = (Iterator) left; - final Iterator rightIterator = (Iterator) right; + right = ((Iterable) right).iterator(); + + final Iterator rightIterator = (Iterator) right; while (rightIterator.hasNext()) { final Object leftItem = rightIterator.next(); while (leftIterator.hasNext()) { final Object rightItem = leftIterator.next(); - if (leftItem != null && leftItem.equals(rightItem)) { + if (leftItem != null && leftItem.equals(rightItem)) return true; - } } } } @@ -85,23 +82,20 @@ public Boolean evaluate(final Identifiable currentRecord, final CommandContext c final Object rightValue = right.execute(currentRecord, context); return execute(leftValue, rightValue); } else { - if (!MultiValue.isMultiValue(leftValue)) { + if (!MultiValue.isMultiValue(leftValue)) return false; - } + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); if (item instanceof Identifiable) { - if (!rightBlock.evaluate((Identifiable) item, context)) { + if (!rightBlock.evaluate((Identifiable) item, context)) return false; - } } else if (item instanceof Result) { - if (!rightBlock.evaluate((Result) item, context)) { + if (!rightBlock.evaluate((Result) item, context)) return false; - } - } else if (!rightBlock.evaluate(new ResultInternal(item), context)) { + } else if (!rightBlock.evaluate(new ResultInternal(item), context)) return false; - } } return true; } @@ -114,23 +108,20 @@ public Boolean evaluate(final Result currentRecord, final CommandContext context final Object rightValue = right.execute(currentRecord, context); return execute(leftValue, rightValue); } else { - if (!MultiValue.isMultiValue(leftValue)) { + if (!MultiValue.isMultiValue(leftValue)) return false; - } + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); if (item instanceof Identifiable) { - if (!rightBlock.evaluate((Identifiable) item, context)) { + if (!rightBlock.evaluate((Identifiable) item, context)) return false; - } } else if (item instanceof Result) { - if (!rightBlock.evaluate((Result) item, context)) { + if (!rightBlock.evaluate((Result) item, context)) return false; - } - } else if (!rightBlock.evaluate(new ResultInternal(item), context)) { + } else if (!rightBlock.evaluate(new ResultInternal(item), context)) return false; - } } return true; } diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsCondition.java b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsCondition.java index 8ab39485b..5ff872428 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsCondition.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/ContainsCondition.java @@ -43,59 +43,56 @@ public ContainsCondition(final int id) { public boolean execute(final Object left, Object right) { if (left instanceof Collection) { if (right instanceof Collection) { - if (((Collection) right).size() == 1) { - Object item = ((Collection) right).iterator().next(); + if (((Collection) right).size() == 1) { + Object item = ((Collection) right).iterator().next(); if (item instanceof Result && ((Result) item).getPropertyNames().size() == 1) { final Object propValue = ((Result) item).getProperty(((Result) item).getPropertyNames().iterator().next()); - if (((Collection) left).contains(propValue)) { + if (((Collection) left).contains(propValue)) return true; - } } - if (((Collection) left).contains(item)) { + if (((Collection) left).contains(item)) return true; - } + if (item instanceof Result) item = ((Result) item).getElement().orElse(null); - if (item instanceof Identifiable && ((Collection) left).contains(item)) + if (item instanceof Identifiable && ((Collection) left).contains(item)) return true; } return MultiValue.contains(left, right); } - if (right instanceof Iterable) { - right = ((Iterable) right).iterator(); - } - if (right instanceof Iterator) { - final Iterator iterator = (Iterator) right; + + if (right instanceof Iterable) + right = ((Iterable) right).iterator(); + + if (right instanceof Iterator iterator) { while (iterator.hasNext()) { final Object next = iterator.next(); - if (!((Collection) left).contains(next)) { + if (!((Collection) left).contains(next)) return false; - } } } - for (final Object o : (Collection) left) { - if (equalsInContainsSpace(o, right)) { + for (final Object o : (Collection) left) { + if (equalsInContainsSpace(o, right)) return true; - } } return false; } - Iterator leftIterator = null; - if (left instanceof Iterable) { - leftIterator = ((Iterable) left).iterator(); - } else if (left instanceof Iterator) { - leftIterator = (Iterator) left; - } + Iterator leftIterator = null; + if (left instanceof Iterable) + leftIterator = ((Iterable) left).iterator(); + else if (left instanceof Iterator) + leftIterator = (Iterator) left; + if (leftIterator != null) { - if (!(right instanceof Iterable)) { + if (!(right instanceof Iterable)) right = Collections.singleton(right); - } - right = ((Iterable) right).iterator(); - final Iterator rightIterator = (Iterator) right; + right = ((Iterable) right).iterator(); + + final Iterator rightIterator = (Iterator) right; while (rightIterator.hasNext()) { final Object leftItem = rightIterator.next(); boolean found = false; @@ -107,17 +104,15 @@ public boolean execute(final Object left, Object right) { } } - if (!found) { + if (!found) return false; - } // here left iterator should go from beginning, that can be done only for iterable // if left at input is iterator result can be invalid // TODO what if left is Iterator!!!???, should we make temporary Collection , to be able to // iterate from beginning - if (left instanceof Iterable) { - leftIterator = ((Iterable) left).iterator(); - } + if (left instanceof Iterable) + leftIterator = ((Iterable) left).iterator(); } return true; } @@ -125,11 +120,10 @@ public boolean execute(final Object left, Object right) { } private boolean equalsInContainsSpace(final Object left, final Object right) { - if (left == null && right == null) { + if (left == null && right == null) return true; - } else { + else return QueryOperatorEquals.equals(left, right); - } } @Override @@ -139,9 +133,9 @@ public Boolean evaluate(final Identifiable currentRecord, final CommandContext c final Object rightValue = right.execute(currentRecord, context); return execute(leftValue, rightValue); } else { - if (!MultiValue.isMultiValue(leftValue)) { + if (!MultiValue.isMultiValue(leftValue)) return false; - } + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); @@ -163,9 +157,9 @@ public Boolean evaluate(final Result currentRecord, final CommandContext context final Object rightValue = right.execute(currentRecord, context); return execute(leftValue, rightValue); } else { - if (!MultiValue.isMultiValue(leftValue)) { + if (!MultiValue.isMultiValue(leftValue)) return false; - } + final Iterator iter = MultiValue.getMultiValueIterator(leftValue); while (iter.hasNext()) { final Object item = iter.next(); @@ -226,7 +220,7 @@ public List getMatchPatternInvolvedAliases() { final List rightX = right == null ? null : right.getMatchPatternInvolvedAliases(); final List conditionX = condition == null ? null : condition.getMatchPatternInvolvedAliases(); - final List result = new ArrayList(); + final List result = new ArrayList<>(); if (leftX != null) result.addAll(leftX); @@ -247,9 +241,8 @@ protected SimpleNode[] getCacheableElements() { public boolean isIndexAware(final IndexSearchInfo info) { if (left.isBaseIdentifier()) { if (info.getField().equals(left.getDefaultAlias().getStringValue())) { - if (right != null) { + if (right != null) return right.isEarlyCalculated(info.getContext()); - } } } return false; diff --git a/engine/src/main/java/com/arcadedb/query/sql/parser/InOperator.java b/engine/src/main/java/com/arcadedb/query/sql/parser/InOperator.java index eb3a504f9..12a49124c 100644 --- a/engine/src/main/java/com/arcadedb/query/sql/parser/InOperator.java +++ b/engine/src/main/java/com/arcadedb/query/sql/parser/InOperator.java @@ -31,36 +31,32 @@ public InOperator(final int id) { @Override public boolean execute(final DatabaseInternal database, Object left, Object right) { - if (left == null) { - return false; - } if (right instanceof Collection) { - if (left instanceof Collection) { - return ((Collection) right).containsAll((Collection) left); - } - if (left instanceof Iterable) { - left = ((Iterable) left).iterator(); - } - if (left instanceof Iterator) { - final Iterator iterator = (Iterator) left; + if (left instanceof Collection) + return ((Collection) right).containsAll((Collection) left); + + if (left instanceof Iterable) + left = ((Iterable) left).iterator(); + + if (left instanceof Iterator iterator) { while (iterator.hasNext()) { final Object next = iterator.next(); - if (!((Collection) right).contains(next)) { + if (!((Collection) right).contains(next)) { return false; } } } - return ((Collection) right).contains(left); - } - if (right instanceof Iterable) { - right = ((Iterable) right).iterator(); + return ((Collection) right).contains(left); } - if (right instanceof Iterator) { - if (left instanceof Iterable) { - left = ((Iterable) left).iterator(); - } - final Iterator leftIterator = (Iterator) left; - final Iterator rightIterator = (Iterator) right; + + if (right instanceof Iterable) + right = ((Iterable) right).iterator(); + + if (right instanceof Iterator rightIterator) { + if (left instanceof Iterable) + left = ((Iterable) left).iterator(); + + final Iterator leftIterator = (Iterator) left; while (leftIterator.hasNext()) { final Object leftItem = leftIterator.next(); boolean found = false; @@ -71,9 +67,9 @@ public boolean execute(final DatabaseInternal database, Object left, Object righ break; } } - if (!found) { + if (!found) return false; - } + } return true; } diff --git a/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsAllConditionTest.java b/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsAllConditionTest.java new file mode 100644 index 000000000..ccd3b87a9 --- /dev/null +++ b/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsAllConditionTest.java @@ -0,0 +1,93 @@ +/* + * Copyright © 2021-present Arcade Data Ltd (info@arcadedata.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) + * SPDX-License-Identifier: Apache-2.0 + */ +package com.arcadedb.query.sql.parser.operators; + +import com.arcadedb.query.sql.parser.ContainsAllCondition; +import org.junit.jupiter.api.Test; + +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Luca Garulli (l.garulli-(at)-arcadedata.com) + */ +public class ContainsAllConditionTest { + @Test + public void test() { + final ContainsAllCondition op = new ContainsAllCondition(-1); + + assertThat(op.execute(null, null)).isFalse(); + assertThat(op.execute(null, "foo")).isFalse(); + + final List left = new ArrayList<>(); + assertThat(op.execute(left, "foo")).isFalse(); + assertThat(op.execute(left, null)).isFalse(); + + left.add("foo"); + left.add("bar"); + + assertThat(op.execute(left, "foo")).isTrue(); + assertThat(op.execute(left, "bar")).isTrue(); + assertThat(op.execute(left, "fooz")).isFalse(); + + left.add(null); + assertThat(op.execute(left, null)).isTrue(); + + final List right = new ArrayList<>(); + left.add("foo"); + left.add("bar"); + + assertThat(op.execute(left, right)).isTrue(); + } + + @Test + public void testIterable() { + final Iterable left = new Iterable<>() { + private final List ls = Arrays.asList(3, 1, 2); + + @Override + public Iterator iterator() { + return ls.iterator(); + } + }; + + final Iterable right = new Iterable<>() { + private final List ls = Arrays.asList(2, 3); + + @Override + public Iterator iterator() { + return ls.iterator(); + } + }; + + final ContainsAllCondition op = new ContainsAllCondition(-1); + assertThat(op.execute(left, right)).isFalse(); + } + + @Test + public void issue1785() { + final ContainsAllCondition op = new ContainsAllCondition(-1); + + final List nullList = new ArrayList<>(); + nullList.add(null); + + assertThat(op.execute(nullList, nullList)).isTrue(); + } +} diff --git a/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsAnyConditionTest.java b/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsAnyConditionTest.java new file mode 100644 index 000000000..c2ff96d71 --- /dev/null +++ b/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsAnyConditionTest.java @@ -0,0 +1,88 @@ +/* + * Copyright © 2021-present Arcade Data Ltd (info@arcadedata.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-FileCopyrightText: 2021-present Arcade Data Ltd (info@arcadedata.com) + * SPDX-License-Identifier: Apache-2.0 + */ +package com.arcadedb.query.sql.parser.operators; + +import com.arcadedb.query.sql.parser.ContainsAnyCondition; +import com.arcadedb.query.sql.parser.ContainsAnyCondition; +import org.junit.jupiter.api.Test; + +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Luca Garulli (l.garulli-(at)-arcadedata.com) + */ +public class ContainsAnyConditionTest { + @Test + public void test() { + final ContainsAnyCondition op = new ContainsAnyCondition(-1); + + assertThat(op.execute(null, null)).isFalse(); + assertThat(op.execute(null, "foo")).isFalse(); + + final List left = new ArrayList<>(); + assertThat(op.execute(left, "foo")).isFalse(); + assertThat(op.execute(left, null)).isFalse(); + + left.add("foo"); + left.add("bar"); + + assertThat(op.execute(left, "foo")).isTrue(); + assertThat(op.execute(left, "bar")).isTrue(); + assertThat(op.execute(left, "fooz")).isFalse(); + + left.add(null); + assertThat(op.execute(left, null)).isTrue(); + } + + @Test + public void testIterable() { + final Iterable left = new Iterable() { + private final List ls = Arrays.asList(3, 1, 2); + + @Override + public Iterator iterator() { + return ls.iterator(); + } + }; + + final Iterable right = new Iterable() { + private final List ls = Arrays.asList(2, 3); + + @Override + public Iterator iterator() { + return ls.iterator(); + } + }; + + final ContainsAnyCondition op = new ContainsAnyCondition(-1); + assertThat(op.execute(left, right)).isTrue(); + } + + @Test + public void issue1785() { + final ContainsAnyCondition op = new ContainsAnyCondition(-1); + + final List nullList = new ArrayList<>(); + nullList.add(null); + + assertThat(op.execute(nullList, nullList)).isTrue(); + } +} diff --git a/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsConditionTest.java b/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsConditionTest.java index da27d7d81..77fb5cc06 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsConditionTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/parser/operators/ContainsConditionTest.java @@ -19,6 +19,7 @@ package com.arcadedb.query.sql.parser.operators; import com.arcadedb.query.sql.parser.ContainsCondition; +import com.arcadedb.query.sql.parser.InOperator; import org.junit.jupiter.api.Test; import java.util.*; @@ -36,7 +37,7 @@ public void test() { assertThat(op.execute(null, null)).isFalse(); assertThat(op.execute(null, "foo")).isFalse(); - final List left = new ArrayList(); + final List left = new ArrayList<>(); assertThat(op.execute(left, "foo")).isFalse(); assertThat(op.execute(left, null)).isFalse(); @@ -53,7 +54,7 @@ public void test() { @Test public void testIterable() { - final Iterable left = new Iterable() { + final Iterable left = new Iterable<>() { private final List ls = Arrays.asList(3, 1, 2); @Override @@ -62,7 +63,7 @@ public Iterator iterator() { } }; - final Iterable right = new Iterable() { + final Iterable right = new Iterable<>() { private final List ls = Arrays.asList(2, 3); @Override @@ -74,4 +75,14 @@ public Iterator iterator() { final ContainsCondition op = new ContainsCondition(-1); assertThat(op.execute(left, right)).isTrue(); } + + @Test + public void issue1785() { + final ContainsCondition op = new ContainsCondition(-1); + + final List nullList = new ArrayList<>(); + nullList.add(null); + + assertThat(op.execute(nullList, nullList)).isTrue(); + } } diff --git a/engine/src/test/java/com/arcadedb/query/sql/parser/operators/InOperatorTest.java b/engine/src/test/java/com/arcadedb/query/sql/parser/operators/InOperatorTest.java index 6734b46c7..0bfa4757c 100644 --- a/engine/src/test/java/com/arcadedb/query/sql/parser/operators/InOperatorTest.java +++ b/engine/src/test/java/com/arcadedb/query/sql/parser/operators/InOperatorTest.java @@ -49,7 +49,16 @@ public void test() { assertThat(op.execute(null, "foo", list1)).isFalse(); assertThat(op.execute(null, "a", list1)).isTrue(); assertThat(op.execute(null, 1, list1)).isTrue(); + } + + @Test + public void issue1785() { + final InOperator op = new InOperator(-1); + + final List nullList = new ArrayList<>(); + nullList.add(null); - // TODO + assertThat(op.execute(null, null, nullList)).isTrue(); + assertThat(op.execute(null, nullList, nullList)).isTrue(); } }