This is an automated email from the ASF dual-hosted git repository.

jin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hugegraph.git


The following commit(s) were added to refs/heads/master by this push:
     new 470435457 fix(query): handle conflicting edge label conditions safely 
(#2990)
470435457 is described below

commit 470435457daf670cbd90d3ccfbca30721fd83292
Author: contrueCT <[email protected]>
AuthorDate: Mon Apr 13 16:12:31 2026 +0800

    fix(query): handle conflicting edge label conditions safely (#2990)
    
    HugeGraph may read LABEL from a ConditionQuery before the query is 
flattened when optimizing edge traversals. In contradictory label combinations 
such as inE('created').hasLabel('created', 'look').hasLabel('authored'), the 
previous intersection logic reused an empty set to mean both 'not initialized 
yet' and 'already intersected to empty'. That allowed later IN conditions to 
repopulate the candidate set and raised an Illegal key 'LABEL' with more than 
one value error instead of return [...]
    
    Track whether the intersection has been initialized independently so an 
empty intersection remains empty. This keeps the existing protection for true 
multi-value results, while allowing conflicting label predicates to fall back 
safely and produce no matches.
    
    Add regression coverage for the low-level ConditionQuery behavior and for 
the edge traversal scenario from issue #2933, including a match()-based 
equivalent query to assert consistent zero-count results.
---
 .../hugegraph/backend/query/ConditionQuery.java    |  7 ++-
 .../org/apache/hugegraph/core/EdgeCoreTest.java    | 23 ++++++++++
 .../org/apache/hugegraph/unit/core/QueryTest.java  | 50 ++++++++++++++++++++++
 3 files changed, 78 insertions(+), 2 deletions(-)

diff --git 
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQuery.java
 
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQuery.java
index 8a5706a77..063d23aa6 100644
--- 
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQuery.java
+++ 
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQuery.java
@@ -288,11 +288,13 @@ public class ConditionQuery extends IdQuery {
             return value;
         }
 
+        boolean initialized = false;
         Set<Object> intersectValues = InsertionOrderUtil.newSet();
         for (Object value : valuesEQ) {
             List<Object> valueAsList = ImmutableList.of(value);
-            if (intersectValues.isEmpty()) {
+            if (!initialized) {
                 intersectValues.addAll(valueAsList);
+                initialized = true;
             } else {
                 CollectionUtil.intersectWithModify(intersectValues,
                                                    valueAsList);
@@ -301,8 +303,9 @@ public class ConditionQuery extends IdQuery {
         for (Object value : valuesIN) {
             @SuppressWarnings("unchecked")
             List<Object> valueAsList = (List<Object>) value;
-            if (intersectValues.isEmpty()) {
+            if (!initialized) {
                 intersectValues.addAll(valueAsList);
+                initialized = true;
             } else {
                 CollectionUtil.intersectWithModify(intersectValues,
                                                    valueAsList);
diff --git 
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java
 
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java
index 265d40874..6bec6dc06 100644
--- 
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java
+++ 
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java
@@ -4646,6 +4646,29 @@ public class EdgeCoreTest extends BaseCoreTest {
         Assert.assertEquals(3L, size);
     }
 
+    @Test
+    public void testQueryInEdgesOfVertexByConflictingLabels() {
+        HugeGraph graph = graph();
+        init18Edges();
+
+        long direct = graph.traversal().V().inE("created")
+                           .hasLabel("created", "look")
+                           .hasLabel("authored")
+                           .count().next();
+        Assert.assertEquals(0L, direct);
+
+        long matched = graph.traversal().V()
+                            .match(__.as("start1")
+                                     .inE("created")
+                                     .as("m1"))
+                            .select("m1")
+                            .hasLabel("created", "look")
+                            .hasLabel("authored")
+                            .count().next();
+        Assert.assertEquals(0L, matched);
+        Assert.assertEquals(matched, direct);
+    }
+
     @Test
     public void testQueryInEdgesOfVertexBySortkey() {
         HugeGraph graph = graph();
diff --git 
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryTest.java
 
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryTest.java
index 88b161d32..7d48084db 100644
--- 
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryTest.java
+++ 
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/QueryTest.java
@@ -17,8 +17,10 @@
 
 package org.apache.hugegraph.unit.core;
 
+import org.apache.hugegraph.backend.id.Id;
 import org.apache.hugegraph.backend.id.IdGenerator;
 import org.apache.hugegraph.backend.query.Aggregate.AggregateFunc;
+import org.apache.hugegraph.backend.query.Condition;
 import org.apache.hugegraph.backend.query.ConditionQuery;
 import org.apache.hugegraph.backend.query.IdPrefixQuery;
 import org.apache.hugegraph.backend.query.IdQuery;
@@ -30,6 +32,7 @@ import org.apache.hugegraph.type.HugeType;
 import org.apache.hugegraph.type.define.HugeKeys;
 import org.junit.Test;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
@@ -45,6 +48,53 @@ public class QueryTest {
                             query.orders());
     }
 
+    @Test
+    public void testConditionWithEqAndIn() {
+        Id label1 = IdGenerator.of(1);
+        Id label2 = IdGenerator.of(2);
+
+        ConditionQuery query = new ConditionQuery(HugeType.EDGE);
+        query.eq(HugeKeys.LABEL, label1);
+        query.query(Condition.in(HugeKeys.LABEL,
+                                 ImmutableList.of(label1, label2)));
+
+        Assert.assertEquals(label1, query.condition(HugeKeys.LABEL));
+    }
+
+    @Test
+    public void testConditionWithConflictingEqAndIn() {
+        Id label1 = IdGenerator.of(1);
+        Id label2 = IdGenerator.of(2);
+        Id label3 = IdGenerator.of(3);
+
+        ConditionQuery query = new ConditionQuery(HugeType.EDGE);
+        query.eq(HugeKeys.LABEL, label1);
+        query.eq(HugeKeys.LABEL, label2);
+        query.query(Condition.in(HugeKeys.LABEL,
+                                 ImmutableList.of(label1, label3)));
+
+        Assert.assertNull(query.condition(HugeKeys.LABEL));
+    }
+
+    @Test
+    public void testConditionWithMultipleMatchedInValues() {
+        Id label1 = IdGenerator.of(1);
+        Id label2 = IdGenerator.of(2);
+        Id label3 = IdGenerator.of(3);
+        Id label4 = IdGenerator.of(4);
+
+        ConditionQuery query = new ConditionQuery(HugeType.EDGE);
+        query.query(Condition.in(HugeKeys.LABEL,
+                                 ImmutableList.of(label1, label2, label3)));
+        query.query(Condition.in(HugeKeys.LABEL,
+                                 ImmutableList.of(label1, label2, label4)));
+
+        Assert.assertThrows(IllegalStateException.class,
+                            () -> query.condition(HugeKeys.LABEL),
+                            e -> Assert.assertContains("Illegal key 'LABEL'",
+                                                       e.getMessage()));
+    }
+
     @Test
     public void testToString() {
         Query query = new Query(HugeType.VERTEX);

Reply via email to