Copilot commented on code in PR #3039:
URL: https://github.com/apache/hugegraph/pull/3039#discussion_r3333609587


##########
hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java:
##########
@@ -179,7 +193,143 @@ public static void extractHasContainer(HugeGraphStep<?, 
?> newStep,
                 TraversalHelper.copyLabels(step, step.getPreviousStep(), 
false);
                 traversal.removeStep(step);
             }
-        } while (step instanceof HasStep || step instanceof NoOpBarrierStep);
+            step = nextStep;
+        }
+    }
+
+    private static boolean followedByMatchStep(Step<?, ?> step) {
+        Step<?, ?> next = step.getNextStep();
+        while (next instanceof HasStep || next instanceof NoOpBarrierStep) {
+            next = next.getNextStep();
+        }
+        return next instanceof MatchStep;
+    }
+
+    private static boolean hasUnusableMatchPredicate(HugeGraphStep<?, ?> step,
+                                                     HasContainerHolder 
holder) {
+        HugeGraph graph = tryGetGraph(step);
+        for (HasContainer has : holder.getHasContainers()) {
+            if (!hasMatchIndexSensitivePredicate(has)) {
+                continue;
+            }
+            if (graph == null || !hasUsableMatchIndex(graph, step, has)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static void extractUsableHasContainers(HugeGraphStep<?, ?> step,
+                                                   HasContainerHolder holder) {
+        HugeGraph graph = tryGetGraph(step);
+        for (HasContainer has : holder.getHasContainers()) {
+            if (hasMatchIndexSensitivePredicate(has) &&
+                (graph == null || !hasUsableMatchIndex(graph, step, has))) {
+                continue;
+            }
+            if (!GraphStep.processHasContainerIds(step, has)) {
+                step.addHasContainer(has);
+            }
+        }
+    }
+
+    private static boolean hasMatchIndexSensitivePredicate(HasContainer has) {
+        List<P<Object>> predicates = new ArrayList<>();
+        collectPredicates(predicates, ImmutableList.of(has.getPredicate()));
+        for (P<Object> pred : predicates) {
+            BiPredicate<?, ?> bp = pred.getBiPredicate();
+            if (bp == Compare.neq ||
+                bp == Compare.gt || bp == Compare.gte ||
+                bp == Compare.lt || bp == Compare.lte) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean hasUsableMatchIndex(HugeGraph graph,
+                                               HugeGraphStep<?, ?> step,
+                                               HasContainer has) {
+        if (isSysProp(has.getKey())) {
+            return true;
+        }
+
+        PropertyKey pkey = graph.propertyKey(has.getKey());
+
+        Collection<? extends SchemaLabel> schemaLabels = step.returnsVertex() ?
+                                                         graph.vertexLabels() :
+                                                         graph.edgeLabels();
+        boolean seen = false;
+        for (SchemaLabel schemaLabel : schemaLabels) {
+            if (!schemaLabel.properties().contains(pkey.id())) {
+                continue;
+            }
+            seen = true;
+            if (pkey.dataType() == DataType.BOOLEAN &&
+                !hasBooleanIndex(graph, schemaLabel, pkey)) {
+                return false;
+            }
+            if (pkey.dataType().isNumber() &&
+                (!hasOnlyRangePredicates(has) ||
+                 !hasRangeIndex(graph, schemaLabel, pkey))) {
+                return false;
+            }
+            if (pkey.dataType() != DataType.BOOLEAN &&
+                !pkey.dataType().isNumber()) {
+                return false;
+            }
+        }
+        return seen;
+    }
+
+    private static boolean hasBooleanIndex(HugeGraph graph,
+                                           SchemaLabel schemaLabel,
+                                           PropertyKey pkey) {
+        for (Id id : schemaLabel.indexLabels()) {
+            IndexLabel indexLabel = graph.indexLabel(id);
+            if (!matchSingleFieldIndex(indexLabel, pkey)) {
+                continue;
+            }
+            if (indexLabel.indexType().isSecondary() ||
+                indexLabel.indexType().isUnique()) {
+                return true;
+            }

Review Comment:
   `hasBooleanIndex()` treats UNIQUE indexes as queryable (returns true), but 
HugeGraph intentionally does not support querying via unique indexes (see 
`VertexCoreTest#testQueryByUniqueIndex`, which expects `NoIndexException` even 
when a UNIQUE index exists). With the current logic, boolean predicates before 
`match()` could still be pushed down based on a UNIQUE index and then fail in 
backend validation.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to