From 06417ce96d335f66c5875989e5ceee2ff9ca3340 Mon Sep 17 00:00:00 2001 From: Tglman Date: Mon, 9 Dec 2024 22:57:46 +0000 Subject: [PATCH] refactor: minor cleanup in pattern matching logic --- .../core/sql/executor/MatchEdgeTraverser.java | 15 ++-- .../core/sql/executor/MatchFirstStep.java | 2 +- .../executor/MatchReverseEdgeTraverser.java | 4 +- .../orient/core/sql/executor/MatchStep.java | 14 +-- .../sql/executor/OMatchExecutionPlanner.java | 69 +++++++-------- .../core/sql/executor/OptionalMatchStep.java | 6 +- .../orient/core/sql/executor/PatternEdge.java | 34 +++++-- .../orient/core/sql/executor/PatternNode.java | 51 ++++++++--- .../core/sql/parser/OMatchStatement.java | 88 ++++++++++--------- .../orient/core/sql/parser/Pattern.java | 27 +++--- 10 files changed, 182 insertions(+), 128 deletions(-) diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchEdgeTraverser.java b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchEdgeTraverser.java index 1523b69ac7a..0b61e4b422f 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchEdgeTraverser.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchEdgeTraverser.java @@ -23,7 +23,7 @@ public class MatchEdgeTraverser { public MatchEdgeTraverser(OResult lastUpstreamRecord, EdgeTraversal edge) { this.sourceRecord = lastUpstreamRecord; this.edge = edge; - this.item = edge.edge.item; + this.item = edge.edge.getItem(); } public MatchEdgeTraverser(OResult lastUpstreamRecord, OMatchPathItem item) { @@ -53,12 +53,13 @@ public OResult next(OCommandContext ctx) { result.setProperty(prop, sourceRecord.getProperty(prop)); } result.setProperty(endPointAlias, toResult(nextElement)); - if (edge.edge.item.getFilter().getDepthAlias() != null) { - result.setProperty(edge.edge.item.getFilter().getDepthAlias(), nextR.getMetadata("$depth")); + if (edge.edge.getItem().getFilter().getDepthAlias() != null) { + result.setProperty( + edge.edge.getItem().getFilter().getDepthAlias(), nextR.getMetadata("$depth")); } - if (edge.edge.item.getFilter().getPathAlias() != null) { + if (edge.edge.getItem().getFilter().getPathAlias() != null) { result.setProperty( - edge.edge.item.getFilter().getPathAlias(), nextR.getMetadata("$matchPath")); + edge.edge.getItem().getFilter().getPathAlias(), nextR.getMetadata("$matchPath")); } return result; } @@ -78,14 +79,14 @@ protected Object toResult(OIdentifiable nextElement) { } protected String getStartingPointAlias() { - return this.edge.edge.out.alias; + return this.edge.edge.getOut().getAlias(); } protected String getEndpointAlias() { if (this.item != null) { return this.item.getFilter().getAlias(); } - return this.edge.edge.in.alias; + return this.edge.edge.getIn().getAlias(); } protected void init(OCommandContext ctx) { diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchFirstStep.java b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchFirstStep.java index 9be2c866afc..2c91f139d31 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchFirstStep.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchFirstStep.java @@ -73,6 +73,6 @@ public String prettyPrint(int depth, int indent) { } private String getAlias() { - return this.node.alias; + return this.node.getAlias(); } } diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchReverseEdgeTraverser.java b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchReverseEdgeTraverser.java index 27b1c420c4f..2fd33b39ed3 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchReverseEdgeTraverser.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchReverseEdgeTraverser.java @@ -15,8 +15,8 @@ public class MatchReverseEdgeTraverser extends MatchEdgeTraverser { public MatchReverseEdgeTraverser(OResult lastUpstreamRecord, EdgeTraversal edge) { super(lastUpstreamRecord, edge); - this.startingPointAlias = edge.edge.in.alias; - this.endPointAlias = edge.edge.out.alias; + this.startingPointAlias = edge.edge.getIn().getAlias(); + this.endPointAlias = edge.edge.getOut().getAlias(); } protected String targetClassName(OMatchPathItem item, OCommandContext iCommandContext) { diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchStep.java b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchStep.java index 668fb1c50a3..3eb3375f6ad 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchStep.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/MatchStep.java @@ -31,9 +31,9 @@ public OExecutionStream createNextResultSet(OResult lastUpstreamRecord, OCommand } protected MatchEdgeTraverser createTraverser(OResult lastUpstreamRecord) { - if (edge.edge.item instanceof OMultiMatchPathItem) { + if (edge.edge.getItem() instanceof OMultiMatchPathItem) { return new MatchMultiEdgeTraverser(lastUpstreamRecord, edge); - } else if (edge.edge.item instanceof OFieldMatchPathItem) { + } else if (edge.edge.getItem() instanceof OFieldMatchPathItem) { return new MatchFieldTraverser(lastUpstreamRecord, edge); } else if (edge.out) { return new MatchEdgeTraverser(lastUpstreamRecord, edge); @@ -55,14 +55,14 @@ public String prettyPrint(int depth, int indent) { } result.append(spaces); result.append(" "); - result.append("{" + edge.edge.out.alias + "}"); - if (edge.edge.item instanceof OFieldMatchPathItem) { + result.append("{" + edge.edge.getOut().getAlias() + "}"); + if (edge.edge.getItem() instanceof OFieldMatchPathItem) { result.append("."); - result.append(((OFieldMatchPathItem) edge.edge.item).getField()); + result.append(((OFieldMatchPathItem) edge.edge.getItem()).getField()); } else { - result.append(edge.edge.item.getMethod()); + result.append(edge.edge.getItem().getMethod()); } - result.append("{" + edge.edge.in.alias + "}"); + result.append("{" + edge.edge.getIn().getAlias() + "}"); return result.toString(); } } diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/OMatchExecutionPlanner.java b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/OMatchExecutionPlanner.java index aa6a8c9fbab..628dd9ef419 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/OMatchExecutionPlanner.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/OMatchExecutionPlanner.java @@ -250,12 +250,9 @@ private void manageNotPatterns( throw new OCommandExecutionException( "This kind of NOT expression is not supported (yet): " + item.toString()); } - PatternEdge edge = new PatternEdge(); - edge.item = item; - edge.out = new PatternNode(); - edge.out.alias = lastFilter.getAlias(); - edge.in = new PatternNode(); - edge.in.alias = item.getFilter().getAlias(); + PatternNode in = new PatternNode(item.getFilter().getAlias()); + PatternNode out = new PatternNode(lastFilter.getAlias()); + PatternEdge edge = new PatternEdge(item, in, out); EdgeTraversal traversal = new EdgeTraversal(edge, true); MatchStep step = new MatchStep(context, traversal, enableProfiling); steps.add(step); @@ -301,27 +298,27 @@ private OInternalExecutionPlan createPlanForPattern( boolean first = true; if (sortedEdges.size() > 0) { for (EdgeTraversal edge : sortedEdges) { - if (edge.edge.out.alias != null) { - edge.setLeftClass(aliasClasses.get(edge.edge.out.alias)); - edge.setLeftCluster(aliasClusters.get(edge.edge.out.alias)); - edge.setLeftRid(aliasRids.get(edge.edge.out.alias)); - edge.setLeftClass(aliasClasses.get(edge.edge.out.alias)); - edge.setLeftFilter(aliasFilters.get(edge.edge.out.alias)); + if (edge.edge.getOut().getAlias() != null) { + edge.setLeftClass(aliasClasses.get(edge.edge.getOut().getAlias())); + edge.setLeftCluster(aliasClusters.get(edge.edge.getOut().getAlias())); + edge.setLeftRid(aliasRids.get(edge.edge.getOut().getAlias())); + edge.setLeftClass(aliasClasses.get(edge.edge.getOut().getAlias())); + edge.setLeftFilter(aliasFilters.get(edge.edge.getOut().getAlias())); } addStepsFor(plan, edge, context, first, profilingEnabled); first = false; } } else { PatternNode node = pattern.getAliasToNode().values().iterator().next(); - if (prefetchedAliases.contains(node.alias)) { + if (prefetchedAliases.contains(node.getAlias())) { // from prefetch plan.chain(new MatchFirstStep(context, node, profilingEnabled)); } else { // from actual execution plan - String clazz = aliasClasses.get(node.alias); - String cluster = aliasClusters.get(node.alias); - ORid rid = aliasRids.get(node.alias); - OWhereClause filter = aliasFilters.get(node.alias); + String clazz = aliasClasses.get(node.getAlias()); + String cluster = aliasClusters.get(node.getAlias()); + ORid rid = aliasRids.get(node.getAlias()); + OWhereClause filter = aliasFilters.get(node.getAlias()); OSelectStatement select = createSelectStatement(clazz, cluster, rid, filter); plan.chain( new MatchFirstStep( @@ -455,15 +452,15 @@ private void updateScheduleStartingAt( // into them. visitedNodes.add(startNode); for (Set dependencies : remainingDependencies.values()) { - dependencies.remove(startNode.alias); + dependencies.remove(startNode.getAlias()); } Map edges = new LinkedHashMap(); - for (PatternEdge outEdge : startNode.out) { + for (PatternEdge outEdge : startNode.getOut()) { edges.put(outEdge, true); } - for (PatternEdge inEdge : startNode.in) { - if (inEdge.item.isBidirectional()) { + for (PatternEdge inEdge : startNode.getIn()) { + if (inEdge.getItem().isBidirectional()) { edges.put(inEdge, false); } } @@ -471,9 +468,9 @@ private void updateScheduleStartingAt( for (Map.Entry edgeData : edges.entrySet()) { PatternEdge edge = edgeData.getKey(); boolean isOutbound = edgeData.getValue(); - PatternNode neighboringNode = isOutbound ? edge.in : edge.out; + PatternNode neighboringNode = isOutbound ? edge.getIn() : edge.getOut(); - if (!remainingDependencies.get(neighboringNode.alias).isEmpty()) { + if (!remainingDependencies.get(neighboringNode.getAlias()).isEmpty()) { // Unsatisfied dependencies, ignore this neighboring node. continue; } @@ -501,7 +498,7 @@ private void updateScheduleStartingAt( // not allowed // to flip their directionality, so we leave them as-is. boolean traversalDirection; - if (startNode.optional || edge.item.isBidirectional()) { + if (startNode.isOptional() || edge.getItem().isBidirectional()) { traversalDirection = !isOutbound; } else { traversalDirection = isOutbound; @@ -510,7 +507,7 @@ private void updateScheduleStartingAt( visitedEdges.add(edge); resultingSchedule.add(new EdgeTraversal(edge, traversalDirection)); } - } else if (!startNode.optional || isOptionalChain(startNode, edge, neighboringNode)) { + } else if (!startNode.isOptional() || isOptionalChain(startNode, edge, neighboringNode)) { // If the neighboring node wasn't visited, we don't expand the optional node into it, hence // the above check. // Instead, we'll allow the neighboring node to add the edge we failed to visit, via the @@ -548,10 +545,10 @@ private boolean isOptionalChain( visitedEdges.add(edge); - if (neighboringNode.out != null) { - for (PatternEdge patternEdge : neighboringNode.out) { + if (neighboringNode.getOut() != null) { + for (PatternEdge patternEdge : neighboringNode.getOut()) { if (!visitedEdges.contains(patternEdge) - && !isOptionalChain(neighboringNode, patternEdge, patternEdge.in, visitedEdges)) { + && !isOptionalChain(neighboringNode, patternEdge, patternEdge.getIn(), visitedEdges)) { return false; } } @@ -572,7 +569,7 @@ private Map> getDependencies(Pattern pattern) { for (PatternNode node : pattern.aliasToNode.values()) { Set currentDependencies = new HashSet(); - OWhereClause filter = aliasFilters.get(node.alias); + OWhereClause filter = aliasFilters.get(node.getAlias()); if (filter != null && filter.getBaseExpression() != null) { List involvedAliases = filter.getBaseExpression().getMatchPatternInvolvedAliases(); if (involvedAliases != null) { @@ -580,7 +577,7 @@ private Map> getDependencies(Pattern pattern) { } } - result.put(node.alias, currentDependencies); + result.put(node.getAlias(), currentDependencies); } return result; @@ -601,11 +598,11 @@ private void addStepsFor( boolean first, boolean profilingEnabled) { if (first) { - PatternNode patternNode = edge.out ? edge.edge.out : edge.edge.in; - String clazz = this.aliasClasses.get(patternNode.alias); - String cluster = this.aliasClusters.get(patternNode.alias); - ORid rid = this.aliasRids.get(patternNode.alias); - OWhereClause where = aliasFilters.get(patternNode.alias); + PatternNode patternNode = edge.out ? edge.edge.getOut() : edge.edge.getIn(); + String clazz = this.aliasClasses.get(patternNode.getAlias()); + String cluster = this.aliasClusters.get(patternNode.getAlias()); + ORid rid = this.aliasRids.get(patternNode.getAlias()); + OWhereClause where = aliasFilters.get(patternNode.getAlias()); OSelectStatement select = new OSelectStatement(-1); select.setTarget(new OFromClause(-1)); select.getTarget().setItem(new OFromItem(-1)); @@ -626,7 +623,7 @@ private void addStepsFor( select.createExecutionPlan(subContxt, profilingEnabled), profilingEnabled)); } - if (edge.edge.in.isOptionalNode()) { + if (edge.edge.getIn().isOptionalNode()) { foundOptional = true; plan.chain(new OptionalMatchStep(context, edge, profilingEnabled)); } else { diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/OptionalMatchStep.java b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/OptionalMatchStep.java index fe27a3519b3..ae121088c51 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/OptionalMatchStep.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/OptionalMatchStep.java @@ -26,9 +26,9 @@ public String prettyPrint(int depth, int indent) { } result.append(spaces); result.append(" "); - result.append("{" + edge.edge.out.alias + "}"); - result.append(edge.edge.item.getMethod()); - result.append("{" + edge.edge.in.alias + "}"); + result.append("{" + edge.edge.getOut().getAlias() + "}"); + result.append(edge.edge.getItem().getMethod()); + result.append("{" + edge.edge.getIn().getAlias() + "}"); return result.toString(); } } diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/PatternEdge.java b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/PatternEdge.java index 14c0965d28a..9f37ea9e78f 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/PatternEdge.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/PatternEdge.java @@ -7,20 +7,44 @@ /** Created by luigidellaquila on 28/07/15. */ public class PatternEdge { - public PatternNode in; - public PatternNode out; - public OMatchPathItem item; + private final PatternNode in; + private final PatternNode out; + private final OMatchPathItem item; + + public PatternEdge(OMatchPathItem item, PatternNode in, PatternNode out) { + this.item = item; + this.in = in; + this.out = out; + } public Iterable executeTraversal( OMatchStatement.MatchContext matchContext, OCommandContext iCommandContext, OIdentifiable startingPoint, int depth) { - return item.executeTraversal(matchContext, iCommandContext, startingPoint, depth); + return getItem().executeTraversal(matchContext, iCommandContext, startingPoint, depth); } @Override public String toString() { - return "{as: " + in.alias + "}" + item.toString(); + return "{as: " + + getOut().getAlias() + + "}" + + getItem().toString() + + "{as: " + + getIn().getAlias() + + "}"; + } + + public OMatchPathItem getItem() { + return item; + } + + public PatternNode getOut() { + return out; + } + + public PatternNode getIn() { + return in; } } diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/PatternNode.java b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/PatternNode.java index 3a47731de12..7ebcbab1b5d 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/executor/PatternNode.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/executor/PatternNode.java @@ -6,23 +6,52 @@ /** Created by luigidellaquila on 28/07/15. */ public class PatternNode { - public String alias; - public Set out = new LinkedHashSet(); - public Set in = new LinkedHashSet(); - public int centrality = 0; - public boolean optional = false; + private final String alias; + private final Set out = new LinkedHashSet(); + private final Set in = new LinkedHashSet(); + private int centrality = 0; + private boolean optional = false; + + public PatternNode(String alias) { + this.alias = alias; + } public int addEdge(OMatchPathItem item, PatternNode to) { - PatternEdge edge = new PatternEdge(); - edge.item = item; - edge.out = this; - edge.in = to; - this.out.add(edge); - to.in.add(edge); + PatternEdge edge = new PatternEdge(item, to, this); + this.getOut().add(edge); + to.getIn().add(edge); return 1; } public boolean isOptionalNode() { + return isOptional(); + } + + public boolean isOptional() { return optional; } + + public void setOptional(boolean optional) { + this.optional = optional; + } + + public int getCentrality() { + return centrality; + } + + public void setCentrality(int centrality) { + this.centrality = centrality; + } + + public Set getIn() { + return in; + } + + public Set getOut() { + return out; + } + + public String getAlias() { + return alias; + } } diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/parser/OMatchStatement.java b/core/src/main/java/com/orientechnologies/orient/core/sql/parser/OMatchStatement.java index 56bc25b8aa1..d37d8d6b16e 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/parser/OMatchStatement.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/parser/OMatchStatement.java @@ -460,23 +460,23 @@ private void updateScheduleStartingAt( // into them. visitedNodes.add(startNode); for (Set dependencies : remainingDependencies.values()) { - dependencies.remove(startNode.alias); + dependencies.remove(startNode.getAlias()); } Map edges = new LinkedHashMap(); - for (PatternEdge outEdge : startNode.out) { + for (PatternEdge outEdge : startNode.getOut()) { edges.put(outEdge, true); } - for (PatternEdge inEdge : startNode.in) { + for (PatternEdge inEdge : startNode.getIn()) { edges.put(inEdge, false); } for (Map.Entry edgeData : edges.entrySet()) { PatternEdge edge = edgeData.getKey(); boolean isOutbound = edgeData.getValue(); - PatternNode neighboringNode = isOutbound ? edge.in : edge.out; + PatternNode neighboringNode = isOutbound ? edge.getIn() : edge.getOut(); - if (!remainingDependencies.get(neighboringNode.alias).isEmpty()) { + if (!remainingDependencies.get(neighboringNode.getAlias()).isEmpty()) { // Unsatisfied dependencies, ignore this neighboring node. continue; } @@ -504,7 +504,7 @@ private void updateScheduleStartingAt( // not allowed // to flip their directionality, so we leave them as-is. boolean traversalDirection; - if (startNode.optional || edge.item.isBidirectional()) { + if (startNode.isOptional() || edge.getItem().isBidirectional()) { traversalDirection = !isOutbound; } else { traversalDirection = isOutbound; @@ -513,7 +513,7 @@ private void updateScheduleStartingAt( visitedEdges.add(edge); resultingSchedule.add(new EdgeTraversal(edge, traversalDirection)); } - } else if (!startNode.optional) { + } else if (!startNode.isOptional()) { // If the neighboring node wasn't visited, we don't expand the optional node into it, hence // the above check. // Instead, we'll allow the neighboring node to add the edge we failed to visit, via the @@ -547,7 +547,7 @@ private Map> getDependencies(Pattern pattern) { for (PatternNode node : pattern.aliasToNode.values()) { Set currentDependencies = new HashSet(); - OWhereClause filter = aliasFilters.get(node.alias); + OWhereClause filter = aliasFilters.get(node.getAlias()); if (filter != null && filter.baseExpression != null) { List involvedAliases = filter.baseExpression.getMatchPatternInvolvedAliases(); if (involvedAliases != null) { @@ -555,7 +555,7 @@ private Map> getDependencies(Pattern pattern) { } } - result.put(node.alias, currentDependencies); + result.put(node.getAlias(), currentDependencies); } return result; @@ -689,9 +689,10 @@ private boolean calculateMatch( String smallestAlias = null; // and choose the most convenient starting point (the most convenient traversal direction) if (firstEdge != null) { - smallestAlias = firstEdge.out ? firstEdge.edge.out.alias : firstEdge.edge.in.alias; + smallestAlias = + firstEdge.out ? firstEdge.edge.getOut().getAlias() : firstEdge.edge.getIn().getAlias(); } else { - smallestAlias = pattern.aliasToNode.values().iterator().next().alias; + smallestAlias = pattern.aliasToNode.values().iterator().next().getAlias(); } executionPlan.rootAlias = smallestAlias; Iterable allCandidates = matchContext.candidates.get(smallestAlias); @@ -783,18 +784,18 @@ && allNodesCalculated(matchContext, pattern)) { pattern, matchContext, aliasClasses, aliasFilters, iCommandContext, request); } EdgeTraversal currentEdge = executionPlan.sortedEdges.get(matchContext.currentEdgeNumber); - PatternNode rootNode = currentEdge.out ? currentEdge.edge.out : currentEdge.edge.in; + PatternNode rootNode = currentEdge.out ? currentEdge.edge.getOut() : currentEdge.edge.getIn(); if (currentEdge.out) { PatternEdge outEdge = currentEdge.edge; if (!matchContext.matchedEdges.containsKey(outEdge)) { - OIdentifiable startingPoint = matchContext.matched.get(outEdge.out.alias); + OIdentifiable startingPoint = matchContext.matched.get(outEdge.getOut().getAlias()); if (startingPoint == null) { // restart from candidates (disjoint patterns? optional? just could not proceed from last // node?) - Iterable rightCandidates = matchContext.candidates.get(outEdge.out.alias); + Iterable rightCandidates = matchContext.candidates.get(outEdge.getOut().getAlias()); if (rightCandidates != null) { if (!processContextFromCandidates( pattern, @@ -805,7 +806,7 @@ && allNodesCalculated(matchContext, pattern)) { iCommandContext, request, rightCandidates, - outEdge.out.alias, + outEdge.getOut().getAlias(), matchContext.currentEdgeNumber)) { return false; } @@ -815,11 +816,11 @@ && allNodesCalculated(matchContext, pattern)) { Object rightValues = outEdge.executeTraversal(matchContext, iCommandContext, startingPoint, 0); - if (outEdge.in.isOptionalNode() + if (outEdge.getIn().isOptionalNode() && (isEmptyResult(rightValues) - || !contains(rightValues, matchContext.matched.get(outEdge.in.alias)))) { - MatchContext childContext = matchContext.copy(outEdge.in.alias, null); - childContext.matched.put(outEdge.in.alias, null); + || !contains(rightValues, matchContext.matched.get(outEdge.getIn().getAlias())))) { + MatchContext childContext = matchContext.copy(outEdge.getIn().getAlias(), null); + childContext.matched.put(outEdge.getIn().getAlias(), null); childContext.currentEdgeNumber = matchContext.currentEdgeNumber + 1; // TODO testOptional 3 match passa con +1 childContext.matchedEdges.put(outEdge, true); @@ -838,7 +839,7 @@ && allNodesCalculated(matchContext, pattern)) { if (!(rightValues instanceof Iterable)) { rightValues = Collections.singleton(rightValues); } - String rightClassName = aliasClasses.get(outEdge.in.alias); + String rightClassName = aliasClasses.get(outEdge.getIn().getAlias()); OClass rightClass = getDatabase().getMetadata().getSchema().getClass(rightClassName); for (OIdentifiable rightValue : (Iterable) rightValues) { if (rightValue == null) { @@ -849,16 +850,16 @@ && allNodesCalculated(matchContext, pattern)) { continue; } Iterable prevMatchedRightValues = - matchContext.candidates.get(outEdge.in.alias); + matchContext.candidates.get(outEdge.getIn().getAlias()); - if (matchContext.matched.containsKey(outEdge.in.alias)) { + if (matchContext.matched.containsKey(outEdge.getIn().getAlias())) { if (matchContext .matched - .get(outEdge.in.alias) + .get(outEdge.getIn().getAlias()) .getIdentity() .equals(rightValue.getIdentity())) { MatchContext childContext = - matchContext.copy(outEdge.in.alias, rightValue.getIdentity()); + matchContext.copy(outEdge.getIn().getAlias(), rightValue.getIdentity()); childContext.currentEdgeNumber = matchContext.currentEdgeNumber + 1; childContext.matchedEdges.put(outEdge, true); if (!processContext( @@ -879,7 +880,7 @@ && allNodesCalculated(matchContext, pattern)) { // values for (OIdentifiable id : prevMatchedRightValues) { if (id.getIdentity().equals(rightValue.getIdentity())) { - MatchContext childContext = matchContext.copy(outEdge.in.alias, id); + MatchContext childContext = matchContext.copy(outEdge.getIn().getAlias(), id); childContext.currentEdgeNumber = matchContext.currentEdgeNumber + 1; childContext.matchedEdges.put(outEdge, true); if (!processContext( @@ -896,7 +897,7 @@ && allNodesCalculated(matchContext, pattern)) { } } else { // searching for neighbors MatchContext childContext = - matchContext.copy(outEdge.in.alias, rightValue.getIdentity()); + matchContext.copy(outEdge.getIn().getAlias(), rightValue.getIdentity()); childContext.currentEdgeNumber = matchContext.currentEdgeNumber + 1; childContext.matchedEdges.put(outEdge, true); if (!processContext( @@ -915,18 +916,21 @@ && allNodesCalculated(matchContext, pattern)) { } else { PatternEdge inEdge = currentEdge.edge; if (!matchContext.matchedEdges.containsKey(inEdge)) { - if (!inEdge.item.isBidirectional()) { + if (!inEdge.getItem().isBidirectional()) { throw new RuntimeException("Invalid pattern to match!"); } if (!matchContext.matchedEdges.containsKey(inEdge)) { Object leftValues = - inEdge.item.method.executeReverse( - matchContext.matched.get(inEdge.in.alias), iCommandContext); - if (inEdge.out.isOptionalNode() + inEdge + .getItem() + .method + .executeReverse( + matchContext.matched.get(inEdge.getIn().getAlias()), iCommandContext); + if (inEdge.getOut().isOptionalNode() && (isEmptyResult(leftValues) - || !contains(leftValues, matchContext.matched.get(inEdge.out.alias)))) { - MatchContext childContext = matchContext.copy(inEdge.out.alias, null); - childContext.matched.put(inEdge.out.alias, null); + || !contains(leftValues, matchContext.matched.get(inEdge.getOut().getAlias())))) { + MatchContext childContext = matchContext.copy(inEdge.getOut().getAlias(), null); + childContext.matched.put(inEdge.getOut().getAlias(), null); childContext.currentEdgeNumber = matchContext.currentEdgeNumber + 1; childContext.matchedEdges.put(inEdge, true); if (!processContext( @@ -944,7 +948,7 @@ && allNodesCalculated(matchContext, pattern)) { leftValues = Collections.singleton(leftValues); } - String leftClassName = aliasClasses.get(inEdge.out.alias); + String leftClassName = aliasClasses.get(inEdge.getOut().getAlias()); OClass leftClass = getDatabase().getMetadata().getSchema().getClass(leftClassName); for (OIdentifiable leftValue : (Iterable) leftValues) { @@ -956,16 +960,16 @@ && allNodesCalculated(matchContext, pattern)) { continue; } Iterable prevMatchedRightValues = - matchContext.candidates.get(inEdge.out.alias); + matchContext.candidates.get(inEdge.getOut().getAlias()); - if (matchContext.matched.containsKey(inEdge.out.alias)) { + if (matchContext.matched.containsKey(inEdge.getOut().getAlias())) { if (matchContext .matched - .get(inEdge.out.alias) + .get(inEdge.getOut().getAlias()) .getIdentity() .equals(leftValue.getIdentity())) { MatchContext childContext = - matchContext.copy(inEdge.out.alias, leftValue.getIdentity()); + matchContext.copy(inEdge.getOut().getAlias(), leftValue.getIdentity()); childContext.currentEdgeNumber = matchContext.currentEdgeNumber + 1; childContext.matchedEdges.put(inEdge, true); if (!processContext( @@ -986,7 +990,7 @@ && allNodesCalculated(matchContext, pattern)) { // values for (OIdentifiable id : prevMatchedRightValues) { if (id.getIdentity().equals(leftValue.getIdentity())) { - MatchContext childContext = matchContext.copy(inEdge.out.alias, id); + MatchContext childContext = matchContext.copy(inEdge.getOut().getAlias(), id); childContext.currentEdgeNumber = matchContext.currentEdgeNumber + 1; childContext.matchedEdges.put(inEdge, true); @@ -1003,13 +1007,13 @@ && allNodesCalculated(matchContext, pattern)) { } } } else { // searching for neighbors - OWhereClause where = aliasFilters.get(inEdge.out.alias); - String className = aliasClasses.get(inEdge.out.alias); + OWhereClause where = aliasFilters.get(inEdge.getOut().getAlias()); + String className = aliasClasses.get(inEdge.getOut().getAlias()); OClass oClass = getDatabase().getMetadata().getSchema().getClass(className); if ((oClass == null || matchesClass(leftValue, oClass)) && (where == null || where.matchesFilters(leftValue, iCommandContext))) { MatchContext childContext = - matchContext.copy(inEdge.out.alias, leftValue.getIdentity()); + matchContext.copy(inEdge.getOut().getAlias(), leftValue.getIdentity()); childContext.currentEdgeNumber = matchContext.currentEdgeNumber + 1; childContext.matchedEdges.put(inEdge, true); if (!processContext( diff --git a/core/src/main/java/com/orientechnologies/orient/core/sql/parser/Pattern.java b/core/src/main/java/com/orientechnologies/orient/core/sql/parser/Pattern.java index 5bd78f79938..64940fe3ad5 100644 --- a/core/src/main/java/com/orientechnologies/orient/core/sql/parser/Pattern.java +++ b/core/src/main/java/com/orientechnologies/orient/core/sql/parser/Pattern.java @@ -21,7 +21,6 @@ public void addExpression(OMatchExpression expression) { PatternNode originNode = getOrCreateNode(expression.origin); for (OMatchPathItem item : expression.items) { - String nextAlias = item.filter.getAlias(); PatternNode nextNode = getOrCreateNode(item.filter); numOfEdges += originNode.addEdge(item, nextNode); @@ -30,14 +29,14 @@ public void addExpression(OMatchExpression expression) { } private PatternNode getOrCreateNode(OMatchFilter origin) { - PatternNode originNode = get(origin.getAlias()); + String alias = origin.getAlias(); + PatternNode originNode = get(alias); if (originNode == null) { - originNode = new PatternNode(); - originNode.alias = origin.getAlias(); - aliasToNode.put(originNode.alias, originNode); + originNode = new PatternNode(alias); + aliasToNode.put(originNode.getAlias(), originNode); } if (origin.isOptional()) { - originNode.optional = true; + originNode.setOptional(true); } return originNode; } @@ -53,12 +52,12 @@ public int getNumOfEdges() { public void validate() { for (PatternNode node : this.aliasToNode.values()) { if (node.isOptionalNode()) { - if (node.out.size() > 0) { + if (node.getOut().size() > 0) { throw new OCommandSQLParsingException( "In current MATCH version, optional nodes are allowed only on right terminal nodes," + " eg. {} --> {optional:true} is allowed, {optional:true} <-- {} is not. "); } - if (node.in.size() == 0) { + if (node.getIn().size() == 0) { throw new OCommandSQLParsingException( "In current MATCH version, optional nodes must have at least one incoming pattern" + " edge"); @@ -95,11 +94,11 @@ public List getDisjointPatterns() { if (reverseMap.containsKey(currentNode)) { pattern.aliasToNode.put(reverseMap.get(currentNode), currentNode); reverseMap.remove(currentNode); - for (PatternEdge x : currentNode.out) { - toVisit.add(x.in); + for (PatternEdge x : currentNode.getOut()) { + toVisit.add(x.getIn()); } - for (PatternEdge x : currentNode.in) { - toVisit.add(x.out); + for (PatternEdge x : currentNode.getIn()) { + toVisit.add(x.getOut()); } } } @@ -111,10 +110,10 @@ public List getDisjointPatterns() { private void recalculateNumOfEdges() { Map edges = new IdentityHashMap<>(); for (PatternNode node : this.aliasToNode.values()) { - for (PatternEdge edge : node.out) { + for (PatternEdge edge : node.getOut()) { edges.put(edge, edge); } - for (PatternEdge edge : node.in) { + for (PatternEdge edge : node.getIn()) { edges.put(edge, edge); } }