com.arcadedb.query.sql.parser.MatchPathItem Maven / Gradle / Ivy
/*
* Copyright © 2021-present Arcade Data Ltd ([email protected])
*
* 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 ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
/* Generated By:JJTree: Do not edit this line. OMatchPathItem.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=true,NODE_PREFIX=O,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_USERTYPE_VISIBILITY_PUBLIC=true */
package com.arcadedb.query.sql.parser;
import com.arcadedb.database.Document;
import com.arcadedb.database.Identifiable;
import com.arcadedb.database.Record;
import com.arcadedb.exception.ArcadeDBException;
import com.arcadedb.query.sql.executor.CommandContext;
import com.arcadedb.schema.DocumentType;
import java.util.*;
public class MatchPathItem extends SimpleNode {
protected MethodCall method;
protected MatchFilter filter;
public MatchPathItem(final int id) {
super(id);
}
public boolean isBidirectional() {
if (filter.getWhileCondition() != null) {
return false;
}
if (filter.getMaxDepth() != null) {
return false;
}
if (filter.isOptional()) {
return false;
}
return method.isBidirectional();
}
public void toString(final Map params, final StringBuilder builder) {
method.toString(params, builder);
if (filter != null) {
filter.toString(params, builder);
}
}
public Iterable executeTraversal(final MatchStatement.MatchContext matchContext, final CommandContext iCommandContext,
final Identifiable startingPoint, final int depth) {
WhereClause filter = null;
WhereClause whileCondition = null;
Integer maxDepth = null;
DocumentType oClass = null;
if (this.filter != null) {
filter = this.filter.getFilter();
whileCondition = this.filter.getWhileCondition();
maxDepth = this.filter.getMaxDepth();
final String className = this.filter.getTypeName(iCommandContext);
oClass = iCommandContext.getDatabase().getSchema().getType(className);
}
final Set result = new HashSet();
if (whileCondition == null && maxDepth == null) {// in this case starting point is not returned and only one level depth is
// evaluated
final Iterable queryResult = traversePatternEdge(matchContext, startingPoint, iCommandContext);
if (this.filter == null || this.filter.getFilter() == null) {
return queryResult;
}
for (final Identifiable origin : queryResult) {
final Object previousMatch = iCommandContext.getVariable("currentMatch");
iCommandContext.setVariable("currentMatch", origin);
if ((oClass == null || matchesClass(origin, oClass)) && (filter == null || filter.matchesFilters(origin, iCommandContext))) {
result.add(origin);
}
iCommandContext.setVariable("currentMatch", previousMatch);
}
} else {// in this case also zero level (starting point) is considered and traversal depth is given by the while condition
iCommandContext.setVariable("depth", depth);
final Object previousMatch = iCommandContext.getVariable("currentMatch");
iCommandContext.setVariable("currentMatch", startingPoint);
if ((oClass == null || matchesClass(startingPoint, oClass)) && (filter == null || filter.matchesFilters(startingPoint, iCommandContext))) {
result.add(startingPoint);
}
if ((maxDepth == null || depth < maxDepth) && (whileCondition == null || whileCondition.matchesFilters(startingPoint, iCommandContext))) {
final Iterable queryResult = traversePatternEdge(matchContext, startingPoint, iCommandContext);
for (final Identifiable origin : queryResult) {
// TODO consider break strategies (eg. re-traverse nodes)
final Iterable subResult = executeTraversal(matchContext, iCommandContext, origin, depth + 1);
if (subResult instanceof Collection) {
result.addAll((Collection extends Identifiable>) subResult);
} else {
for (final Identifiable i : subResult) {
result.add(i);
}
}
}
}
iCommandContext.setVariable("currentMatch", previousMatch);
}
return result;
}
private boolean matchesClass(final Identifiable identifiable, final DocumentType oClass) {
if (identifiable == null) {
return false;
}
final Record record = identifiable.getRecord();
if (record == null) {
return false;
}
if (record instanceof Document) {
return ((Document) record).getType().isSubTypeOf(oClass.getName());
}
return false;
}
protected Iterable traversePatternEdge(final MatchStatement.MatchContext matchContext, final Identifiable startingPoint,
final CommandContext iCommandContext) {
Iterable possibleResults = null;
if (filter != null) {
final Identifiable matchedNode = matchContext.matched.get(filter.getAlias());
if (matchedNode != null) {
possibleResults = Collections.singleton(matchedNode);
} else if (matchContext.matched.containsKey(filter.getAlias())) {
possibleResults = Collections.emptySet();//optional node, the matched element is a null value
} else {
possibleResults = matchContext.candidates == null ? null : matchContext.candidates.get(filter.getAlias());
}
}
final Object qR = this.method.execute(startingPoint, possibleResults, iCommandContext);
return (qR instanceof Iterable && !(qR instanceof Record)) ? (Iterable) qR : Collections.singleton((Identifiable) qR);
}
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final MatchPathItem that = (MatchPathItem) o;
if (!Objects.equals(method, that.method))
return false;
return Objects.equals(filter, that.filter);
}
@Override
public int hashCode() {
int result = method != null ? method.hashCode() : 0;
result = 31 * result + (filter != null ? filter.hashCode() : 0);
return result;
}
@Override
public MatchPathItem copy() {
final MatchPathItem result;
try {
result = getClass().getConstructor(Integer.TYPE).newInstance(-1);
} catch (final Exception e) {
throw new ArcadeDBException(e);
}
result.method = method == null ? null : method.copy();
result.filter = filter == null ? null : filter.copy();
return result;
}
public MethodCall getMethod() {
return method;
}
public void setMethod(final MethodCall method) {
this.method = method;
}
public MatchFilter getFilter() {
return filter;
}
public void setFilter(final MatchFilter filter) {
this.filter = filter;
}
}
/* JavaCC - OriginalChecksum=ffe8e0ffde583d7b21c9084eff6a8944 (do not edit this line) */
© 2015 - 2025 Weber Informatics LLC | Privacy Policy