You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2017/11/05 20:31:58 UTC
[36/40] atlas git commit: ATLAS-2251: Remove TypeSystem and related
implementation, to avoid unncessary duplicate of type details in cache
http://git-wip-us.apache.org/repos/asf/atlas/blob/0877e47c/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
deleted file mode 100644
index b936695..0000000
--- a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-package org.apache.atlas.gremlin;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.groovy.AbstractFunctionExpression;
-import org.apache.atlas.groovy.CastExpression;
-import org.apache.atlas.groovy.ClosureExpression;
-import org.apache.atlas.groovy.ComparisonExpression;
-import org.apache.atlas.groovy.ComparisonExpression.ComparisonOperator;
-import org.apache.atlas.groovy.ComparisonOperatorExpression;
-import org.apache.atlas.groovy.FieldExpression;
-import org.apache.atlas.groovy.FunctionCallExpression;
-import org.apache.atlas.groovy.GroovyExpression;
-import org.apache.atlas.groovy.IdentifierExpression;
-import org.apache.atlas.groovy.LiteralExpression;
-import org.apache.atlas.groovy.LogicalExpression;
-import org.apache.atlas.groovy.LogicalExpression.LogicalOperator;
-import org.apache.atlas.groovy.TernaryOperatorExpression;
-import org.apache.atlas.groovy.TraversalStepType;
-import org.apache.atlas.groovy.TypeCoersionExpression;
-import org.apache.atlas.query.GraphPersistenceStrategies;
-import org.apache.atlas.query.TypeUtils.FieldInfo;
-import org.apache.atlas.repository.graph.AtlasGraphProvider;
-import org.apache.atlas.repository.graphdb.AtlasGraph;
-import org.apache.atlas.typesystem.types.AttributeInfo;
-import org.apache.atlas.typesystem.types.IDataType;
-
-/**
- * Generates gremlin query expressions using Gremlin 3 syntax.
- *
- */
-public class Gremlin3ExpressionFactory extends GremlinExpressionFactory {
-
-
-
- private static final String VERTEX_LIST_CLASS = "List<Vertex>";
- private static final String VERTEX_ARRAY_CLASS = "Vertex[]";
- private static final String OBJECT_ARRAY_CLASS = "Object[]";
- private static final String VERTEX_CLASS = "Vertex";
- private static final String FUNCTION_CLASS = "Function";
-
- private static final String VALUE_METHOD = "value";
- private static final String IS_PRESENT_METHOD = "isPresent";
- private static final String MAP_METHOD = "map";
- private static final String VALUES_METHOD = "values";
- private static final String GET_METHOD = "get";
- private static final String OR_ELSE_METHOD = "orElse";
- private static final String PROPERTY_METHOD = "property";
- private static final String BY_METHOD = "by";
- private static final String EQ_METHOD = "eq";
- private static final String EMIT_METHOD = "emit";
- private static final String TIMES_METHOD = "times";
- private static final String REPEAT_METHOD = "repeat";
- private static final String RANGE_METHOD = "range";
- private static final String LAST_METHOD = "last";
- private static final String TO_STRING_METHOD = "toString";
-
- private static final GroovyExpression EMPTY_STRING_EXPRESSION = new LiteralExpression("");
-
- @Override
- public GroovyExpression generateLogicalExpression(GroovyExpression parent, String operator,
- List<GroovyExpression> operands) {
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, operator, operands);
- }
-
- @Override
- public GroovyExpression generateBackReferenceExpression(GroovyExpression parent, boolean inSelect, String alias) {
- if (inSelect) {
- return getFieldInSelect();
- } else {
- return new FunctionCallExpression(TraversalStepType.MAP_TO_ELEMENT, parent, SELECT_METHOD, new LiteralExpression(alias));
- }
- }
-
- @Override
- public GroovyExpression typeTestExpression(GraphPersistenceStrategies s, String typeName, GroovyExpression itRef) {
- LiteralExpression superTypeAttrExpr = new LiteralExpression(s.superTypeAttributeName());
- LiteralExpression typeNameExpr = new LiteralExpression(typeName);
- LiteralExpression typeAttrExpr = new LiteralExpression(s.typeAttributeName());
- FunctionCallExpression result = new FunctionCallExpression(TraversalStepType.FILTER, HAS_METHOD, typeAttrExpr, new FunctionCallExpression(EQ_METHOD, typeNameExpr));
- result = new FunctionCallExpression(TraversalStepType.FILTER, result, "or");
- result = new FunctionCallExpression(TraversalStepType.FILTER, result, HAS_METHOD, superTypeAttrExpr, new FunctionCallExpression(EQ_METHOD, typeNameExpr));
- return result;
-
- }
-
- @Override
- public GroovyExpression generateLoopExpression(GroovyExpression parent,GraphPersistenceStrategies s, IDataType dataType, GroovyExpression loopExpr, String alias, Integer times) {
-
- GroovyExpression emitExpr = generateLoopEmitExpression(s, dataType);
-
- GroovyExpression result = new FunctionCallExpression(TraversalStepType.BRANCH, parent, REPEAT_METHOD, loopExpr);
- if (times != null) {
- GroovyExpression timesExpr = new LiteralExpression(times);
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, TIMES_METHOD, timesExpr);
- }
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, EMIT_METHOD, emitExpr);
- return result;
-
- }
-
- @Override
- public GroovyExpression getLoopExpressionParent(GroovyExpression inputQry) {
- GroovyExpression curTraversal = getAnonymousTraversalStartExpression();
- return curTraversal;
- }
-
- private IdentifierExpression getAnonymousTraversalStartExpression() {
- return new IdentifierExpression(TraversalStepType.START, "__");
- }
-
- @Override
- public GroovyExpression generateSelectExpression(GroovyExpression parent, List<LiteralExpression> sourceNames,
- List<GroovyExpression> srcExprs) {
- FunctionCallExpression result = new FunctionCallExpression(TraversalStepType.MAP_TO_VALUE, parent, SELECT_METHOD, sourceNames);
-
- for (GroovyExpression expr : srcExprs) {
- GroovyExpression closure = new ClosureExpression(expr);
- GroovyExpression castClosure = new TypeCoersionExpression(closure, FUNCTION_CLASS);
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, BY_METHOD, castClosure);
- }
- return result;
- }
-
- @Override
- public GroovyExpression generateFieldExpression(GroovyExpression parent, FieldInfo fInfo,
- String propertyName, boolean inSelect) {
-
- AttributeInfo attrInfo = fInfo.attrInfo();
- IDataType attrType = attrInfo.dataType();
- GroovyExpression propertyNameExpr = new LiteralExpression(propertyName);
- //Whether it is the user or shared graph does not matter here, since we're
- //just getting the conversion expression. Ideally that would be moved someplace else.
- AtlasGraph graph = AtlasGraphProvider.getGraphInstance();
- if (inSelect) {
-
- GroovyExpression expr = new FunctionCallExpression(parent, PROPERTY_METHOD, propertyNameExpr);
- expr = new FunctionCallExpression(expr, OR_ELSE_METHOD, LiteralExpression.NULL);
- return graph.generatePersisentToLogicalConversionExpression(expr, attrType);
- } else {
-
- GroovyExpression unmapped = new FunctionCallExpression(TraversalStepType.FLAT_MAP_TO_VALUES, parent, VALUES_METHOD, propertyNameExpr);
- if (graph.isPropertyValueConversionNeeded(attrType)) {
- GroovyExpression toConvert = new FunctionCallExpression(getItVariable(), GET_METHOD);
-
- GroovyExpression conversionFunction = graph.generatePersisentToLogicalConversionExpression(toConvert,
- attrType);
- return new FunctionCallExpression(TraversalStepType.MAP_TO_VALUE, unmapped, MAP_METHOD, new ClosureExpression(conversionFunction));
- } else {
- return unmapped;
- }
-
- }
- }
-
- private ComparisonOperator getGroovyOperator(String symbol) throws AtlasException {
-
- String toFind = symbol;
- if (toFind.equals("=")) {
- toFind = "==";
- }
- return ComparisonOperator.lookup(toFind);
- }
-
- private String getComparisonFunction(String op) throws AtlasException {
-
- if (op.equals("=")) {
- return "eq";
- }
- if (op.equals("!=")) {
- return "neq";
- }
- if (op.equals(">")) {
- return "gt";
- }
- if (op.equals(">=")) {
- return "gte";
- }
- if (op.equals("<")) {
- return "lt";
- }
- if (op.equals("<=")) {
- return "lte";
- }
- throw new AtlasException("Comparison operator " + op + " not supported in Gremlin");
- }
-
- @Override
- public GroovyExpression generateHasExpression(GraphPersistenceStrategies s, GroovyExpression parent,
- String propertyName, String symbol, GroovyExpression requiredValue, FieldInfo fInfo) throws AtlasException {
-
- AttributeInfo attrInfo = fInfo.attrInfo();
- IDataType attrType = attrInfo.dataType();
- GroovyExpression propertNameExpr = new LiteralExpression(propertyName);
- if (s.isPropertyValueConversionNeeded(attrType)) {
- // for some types, the logical value cannot be stored directly in
- // the underlying graph,
- // and conversion logic is needed to convert the persistent form of
- // the value
- // to the actual value. In cases like this, we generate a conversion
- // expression to
- // do this conversion and use the filter step to perform the
- // comparsion in the gremlin query
- GroovyExpression itExpr = getItVariable();
- GroovyExpression vertexExpr = new CastExpression(new FunctionCallExpression(itExpr, GET_METHOD), VERTEX_CLASS);
- GroovyExpression propertyValueExpr = new FunctionCallExpression(vertexExpr, VALUE_METHOD, propertNameExpr);
- GroovyExpression conversionExpr = s.generatePersisentToLogicalConversionExpression(propertyValueExpr,
- attrType);
-
- GroovyExpression propertyIsPresentExpression = new FunctionCallExpression(
- new FunctionCallExpression(vertexExpr, PROPERTY_METHOD, propertNameExpr), IS_PRESENT_METHOD);
- GroovyExpression valueMatchesExpr = new ComparisonExpression(conversionExpr, getGroovyOperator(symbol),
- requiredValue);
-
- GroovyExpression filterCondition = new LogicalExpression(propertyIsPresentExpression, LogicalOperator.AND,
- valueMatchesExpr);
-
- GroovyExpression filterFunction = new ClosureExpression(filterCondition);
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, filterFunction);
- } else {
- GroovyExpression valueMatches = new FunctionCallExpression(getComparisonFunction(symbol), requiredValue);
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, HAS_METHOD, propertNameExpr, valueMatches);
- }
- }
-
- @Override
- public GroovyExpression generateLikeExpressionUsingFilter(GroovyExpression parent, String propertyName, GroovyExpression propertyValue) throws AtlasException {
- GroovyExpression vertexExpr = new FunctionCallExpression(getItVariable(), GET_METHOD);
- GroovyExpression propertyValueExpr = new FunctionCallExpression(vertexExpr, VALUE_METHOD, new LiteralExpression(propertyName));
- GroovyExpression matchesExpr = new FunctionCallExpression(propertyValueExpr, MATCHES, escapePropertyValue(propertyValue));
- GroovyExpression closureExpr = new ClosureExpression(matchesExpr);
-
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, closureExpr);
- }
-
- private GroovyExpression escapePropertyValue(GroovyExpression propertyValue) {
- GroovyExpression ret = propertyValue;
-
- if (propertyValue instanceof LiteralExpression) {
- LiteralExpression exp = (LiteralExpression) propertyValue;
-
- if (exp != null && exp.getValue() instanceof String) {
- String stringValue = (String) exp.getValue();
-
- // replace '*' with ".*", replace '?' with '.'
- stringValue = stringValue.replaceAll("\\*", ".*")
- .replaceAll("\\?", ".");
-
- ret = new LiteralExpression(stringValue);
- }
- }
-
- return ret;
- }
-
- @Override
- protected GroovyExpression initialExpression(GroovyExpression varExpr, GraphPersistenceStrategies s) {
-
- // this bit of groovy magic converts the set of vertices in varName into
- // a String containing the ids of all the vertices. This becomes the
- // argument
- // to g.V(). This is needed because Gremlin 3 does not support
- // _()
- // s"g.V(${varName}.collect{it.id()} as String[])"
-
- GroovyExpression gExpr = getGraphExpression();
- GroovyExpression varRefExpr = new TypeCoersionExpression(varExpr, OBJECT_ARRAY_CLASS);
- GroovyExpression matchingVerticesExpr = new FunctionCallExpression(TraversalStepType.START, gExpr, V_METHOD, varRefExpr);
- GroovyExpression isEmpty = new FunctionCallExpression(varExpr, "isEmpty");
- GroovyExpression emptyGraph = getEmptyTraversalExpression();
-
- GroovyExpression expr = new TernaryOperatorExpression(isEmpty, emptyGraph, matchingVerticesExpr);
-
- return s.addInitialQueryCondition(expr);
- }
-
- private GroovyExpression getEmptyTraversalExpression() {
- GroovyExpression emptyGraph = new FunctionCallExpression(TraversalStepType.START, getGraphExpression(), V_METHOD, EMPTY_STRING_EXPRESSION);
- return emptyGraph;
- }
-
- @Override
- public GroovyExpression generateRangeExpression(GroovyExpression parent, int startIndex, int endIndex) {
- //treat as barrier step, since limits need to be applied globally (even though it
- //is technically a filter step)
- return new FunctionCallExpression(TraversalStepType.BARRIER, parent, RANGE_METHOD, new LiteralExpression(startIndex), new LiteralExpression(endIndex));
- }
-
- @Override
- public boolean isRangeExpression(GroovyExpression expr) {
-
- return (expr instanceof FunctionCallExpression && ((FunctionCallExpression)expr).getFunctionName().equals(RANGE_METHOD));
- }
-
- @Override
- public int[] getRangeParameters(AbstractFunctionExpression expr) {
-
- if (isRangeExpression(expr)) {
- FunctionCallExpression rangeExpression = (FunctionCallExpression) expr;
- List<GroovyExpression> arguments = rangeExpression.getArguments();
- int startIndex = (int)((LiteralExpression)arguments.get(0)).getValue();
- int endIndex = (int)((LiteralExpression)arguments.get(1)).getValue();
- return new int[]{startIndex, endIndex};
- }
- else {
- return null;
- }
- }
-
- @Override
- public void setRangeParameters(GroovyExpression expr, int startIndex, int endIndex) {
-
- if (isRangeExpression(expr)) {
- FunctionCallExpression rangeExpression = (FunctionCallExpression) expr;
- rangeExpression.setArgument(0, new LiteralExpression(Integer.valueOf(startIndex)));
- rangeExpression.setArgument(1, new LiteralExpression(Integer.valueOf(endIndex)));
- }
- else {
- throw new IllegalArgumentException(expr + " is not a valid range expression");
- }
- }
-
- @Override
- public List<GroovyExpression> getOrderFieldParents() {
-
- List<GroovyExpression> result = new ArrayList<>(1);
- result.add(null);
- return result;
- }
-
- @Override
- public GroovyExpression generateOrderByExpression(GroovyExpression parent, List<GroovyExpression> translatedOrderBy,
- boolean isAscending) {
-
- GroovyExpression orderByExpr = translatedOrderBy.get(0);
- GroovyExpression orderByClosure = new ClosureExpression(orderByExpr);
- GroovyExpression orderByClause = new TypeCoersionExpression(orderByClosure, FUNCTION_CLASS);
-
- GroovyExpression aExpr = new IdentifierExpression("a");
- GroovyExpression bExpr = new IdentifierExpression("b");
-
- GroovyExpression aCompExpr = new FunctionCallExpression(new FunctionCallExpression(aExpr, TO_STRING_METHOD), TO_LOWER_CASE_METHOD);
- GroovyExpression bCompExpr = new FunctionCallExpression(new FunctionCallExpression(bExpr, TO_STRING_METHOD), TO_LOWER_CASE_METHOD);
-
- GroovyExpression comparisonExpr = null;
- if (isAscending) {
- comparisonExpr = new ComparisonOperatorExpression(aCompExpr, bCompExpr);
- } else {
- comparisonExpr = new ComparisonOperatorExpression(bCompExpr, aCompExpr);
- }
- ClosureExpression comparisonFunction = new ClosureExpression(comparisonExpr, "a", "b");
- FunctionCallExpression orderCall = new FunctionCallExpression(TraversalStepType.BARRIER, parent, ORDER_METHOD);
- return new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, orderCall, BY_METHOD, orderByClause, comparisonFunction);
- }
-
- @Override
- public GroovyExpression getAnonymousTraversalExpression() {
- return null;
- }
-
- @Override
- public GroovyExpression getFieldInSelect() {
- // this logic is needed to remove extra results from
- // what is emitted by repeat loops. Technically
- // for queries that don't have a loop in them we could just use "it"
- // the reason for this is that in repeat loops with an alias,
- // although the alias gets set to the right value, for some
- // reason the select actually includes all vertices that were traversed
- // through in the loop. In these cases, we only want the last vertex
- // traversed in the loop to be selected. The logic here handles that
- // case by converting the result to a list and just selecting the
- // last item from it.
-
- GroovyExpression itExpr = getItVariable();
- GroovyExpression expr1 = new TypeCoersionExpression(itExpr, VERTEX_ARRAY_CLASS);
- GroovyExpression expr2 = new TypeCoersionExpression(expr1, VERTEX_LIST_CLASS);
-
- return new FunctionCallExpression(expr2, LAST_METHOD);
- }
-
- @Override
- public GroovyExpression generateGroupByExpression(GroovyExpression parent, GroovyExpression groupByExpression,
- GroovyExpression aggregationFunction) {
-
- GroovyExpression result = new FunctionCallExpression(TraversalStepType.BARRIER, parent, "group");
- GroovyExpression groupByClosureExpr = new TypeCoersionExpression(new ClosureExpression(groupByExpression), "Function");
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, "by", groupByClosureExpr);
- result = new FunctionCallExpression(TraversalStepType.END, result, "toList");
-
- GroovyExpression mapValuesClosure = new ClosureExpression(new FunctionCallExpression(new CastExpression(getItVariable(), "Map"), "values"));
-
- result = new FunctionCallExpression(result, "collect", mapValuesClosure);
-
- //when we call Map.values(), we end up with an extra list around the result. We remove this by calling toList().get(0). This
- //leaves us with a list of lists containing the vertices that match each group. We then apply the aggregation functions
- //specified in the select list to each of these inner lists.
-
- result = new FunctionCallExpression(result ,"toList");
- result = new FunctionCallExpression(result, "get", new LiteralExpression(0));
-
- GroovyExpression aggregrationFunctionClosure = new ClosureExpression(aggregationFunction);
- result = new FunctionCallExpression(result, "collect", aggregrationFunctionClosure);
- return result;
- }
-
- @Override
- public GroovyExpression generateSeededTraversalExpresssion(boolean isMap, GroovyExpression valueCollection) {
- GroovyExpression coersedExpression = new TypeCoersionExpression(valueCollection, isMap ? "Map[]" : "Vertex[]");
- if(isMap) {
-
- return new FunctionCallExpression(TraversalStepType.START, "__", coersedExpression);
- }
- else {
- //We cannot always use an anonymous traversal because that breaks repeat steps
- return new FunctionCallExpression(TraversalStepType.START, getEmptyTraversalExpression(), "inject", coersedExpression);
- }
- }
-
- @Override
- public GroovyExpression getGroupBySelectFieldParent() {
- return null;
- }
-
- @Override
- public String getTraversalExpressionClass() {
- return "GraphTraversal";
- }
-
- @Override
- public boolean isSelectGeneratesMap(int aliasCount) {
- //in Gremlin 3, you only get a map if there is more than 1 alias.
- return aliasCount > 1;
- }
-
- @Override
- public GroovyExpression generateMapExpression(GroovyExpression parent, ClosureExpression closureExpression) {
- return new FunctionCallExpression(TraversalStepType.MAP_TO_ELEMENT, parent, "map", closureExpression);
- }
-
- @Override
- public GroovyExpression generateGetSelectedValueExpression(LiteralExpression key,
- GroovyExpression rowMapExpr) {
- rowMapExpr = new CastExpression(rowMapExpr, "Map");
- GroovyExpression getExpr = new FunctionCallExpression(rowMapExpr, "get", key);
- return getExpr;
- }
-
- @Override
- public GroovyExpression getCurrentTraverserObject(GroovyExpression traverser) {
- return new FunctionCallExpression(traverser, "get");
- }
-
- public List<String> getAliasesRequiredByExpression(GroovyExpression expr) {
- return Collections.emptyList();
- }
-
- @Override
- public boolean isRepeatExpression(GroovyExpression expr) {
- if(!(expr instanceof FunctionCallExpression)) {
- return false;
- }
- return ((FunctionCallExpression)expr).getFunctionName().equals(REPEAT_METHOD);
- }
-}
http://git-wip-us.apache.org/repos/asf/atlas/blob/0877e47c/repository/src/main/java/org/apache/atlas/gremlin/GremlinExpressionFactory.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/GremlinExpressionFactory.java b/repository/src/main/java/org/apache/atlas/gremlin/GremlinExpressionFactory.java
deleted file mode 100644
index d603150..0000000
--- a/repository/src/main/java/org/apache/atlas/gremlin/GremlinExpressionFactory.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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_METHOD 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.
- */
-package org.apache.atlas.gremlin;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.groovy.AbstractFunctionExpression;
-import org.apache.atlas.groovy.ArithmeticExpression;
-import org.apache.atlas.groovy.ArithmeticExpression.ArithmeticOperator;
-import org.apache.atlas.groovy.CastExpression;
-import org.apache.atlas.groovy.ClosureExpression;
-import org.apache.atlas.groovy.FieldExpression;
-import org.apache.atlas.groovy.FunctionCallExpression;
-import org.apache.atlas.groovy.GroovyExpression;
-import org.apache.atlas.groovy.IdentifierExpression;
-import org.apache.atlas.groovy.ListExpression;
-import org.apache.atlas.groovy.LiteralExpression;
-import org.apache.atlas.groovy.TraversalStepType;
-import org.apache.atlas.groovy.TypeCoersionExpression;
-import org.apache.atlas.groovy.VariableAssignmentExpression;
-import org.apache.atlas.query.GraphPersistenceStrategies;
-import org.apache.atlas.query.IntSequence;
-import org.apache.atlas.query.TypeUtils.FieldInfo;
-import org.apache.atlas.repository.graph.AtlasGraphProvider;
-import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
-import org.apache.atlas.repository.graphdb.GremlinVersion;
-import org.apache.atlas.typesystem.types.IDataType;
-import org.apache.atlas.typesystem.types.TypeSystem;
-import org.apache.atlas.typesystem.types.cache.TypeCache.TYPE_FILTER;
-import org.apache.atlas.util.AtlasRepositoryConfiguration;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * Factory to generate Groovy expressions representing Gremlin syntax that that
- * are independent of the specific version of Gremlin that is being used.
- *
- */
-public abstract class GremlinExpressionFactory {
-
- private static final String G_VARIABLE = "g";
- private static final String IT_VARIABLE = "it";
-
- protected static final String SET_CLASS = "Set";
-
-
- private static final String OBJECT_FIELD = "object";
-
- protected static final String V_METHOD = "V";
- protected static final String FILTER_METHOD = "filter";
- private static final String PATH_METHOD = "path";
- private static final String AS_METHOD = "as";
- private static final String IN_OPERATOR = "in";
- protected static final String HAS_METHOD = "has";
- protected static final String TO_LOWER_CASE_METHOD = "toLowerCase";
- protected static final String SELECT_METHOD = "select";
- protected static final String ORDER_METHOD = "order";
- protected static final String FILL_METHOD = "fill";
- protected static final String MATCHES = "matches";
-
- public static final GremlinExpressionFactory INSTANCE = AtlasGraphProvider.getGraphInstance()
- .getSupportedGremlinVersion() == GremlinVersion.THREE ? new Gremlin3ExpressionFactory()
- : new Gremlin2ExpressionFactory();
-
- /**
- * Returns the unqualified name of the class used in this version of gremlin to
- * represent Gremlin queries as they are being generated.
- * @return
- */
- public abstract String getTraversalExpressionClass();
-
- /**
- * Gets the expression to use as the parent when translating the loop
- * expression in a loop
- *
- * @param inputQry
- * the
- * @return
- */
- public abstract GroovyExpression getLoopExpressionParent(GroovyExpression inputQry);
-
- /**
- * Generates a loop expression.
- *
- * @param parent
- * the parent of the loop expression
- * @param emitExpr
- * Expression with the value that should be emitted by the loop
- * expression.
- * @param loopExpr
- * the query expression that is being executed repeatedly
- * executed in a loop
- * @param alias
- * The alias of the expression being looped over
- * @param times
- * the number of times to repeat, or null if a times condition
- * should not be used.
- * @return
- */
- public abstract GroovyExpression generateLoopExpression(GroovyExpression parent, GraphPersistenceStrategies s, IDataType dataType,
- GroovyExpression loopExpr, String alias, Integer times);
-
-
- /**
- * Generates a logical (and/or) expression with the given operands.
- * @param parent
- * @param operator
- * @param operands
- * @return
- */
- public abstract GroovyExpression generateLogicalExpression(GroovyExpression parent, String operator,
- List<GroovyExpression> operands);
-
- /**
- * Generates a back reference expression that refers to the given alias.
- *
- * @param parent
- * @param inSelect
- * @param alias
- * @return
- */
- public abstract GroovyExpression generateBackReferenceExpression(GroovyExpression parent, boolean inSelect,
- String alias);
-
- /**
- * Generates a select expression
- *
- * @param parent
- * @param sourceNames
- * the names of the select fields
- * @param srcExprs
- * the corresponding values to return
- * @return
- */
- public abstract GroovyExpression generateSelectExpression(GroovyExpression parent,
- List<LiteralExpression> sourceNames, List<GroovyExpression> srcExprs);
-
- /**
- * Generates a an expression that gets the value of the given property from the
- * vertex presented by the parent.
- *
- * @param parent
- * @param fInfo
- * @param propertyName
- * @param inSelect
- * @return
- */
- public abstract GroovyExpression generateFieldExpression(GroovyExpression parent, FieldInfo fInfo,
- String propertyName, boolean inSelect);
-
- /**
- * Generates a has expression that checks whether the vertices match a specific condition
- *
- * @param s
- * @param parent the object that we should call apply the "has" condition to.
- * @param propertyName the name of the property whose value we are comparing
- * @param symbol comparsion operator symbol ('=','<', etc.)
- * @param requiredValue the value to compare against
- * @param fInfo info about the field whose value we are checking
- * @return
- * @throws AtlasException
- */
- public abstract GroovyExpression generateHasExpression(GraphPersistenceStrategies s, GroovyExpression parent,
- String propertyName, String symbol, GroovyExpression requiredValue, FieldInfo fInfo) throws AtlasException;
-
- public abstract GroovyExpression generateLikeExpressionUsingFilter(GroovyExpression parent, String propertyName,
- GroovyExpression propertyValue) throws AtlasException;
-
- /**
- * Generates a range expression
- *
- * @param parent
- * @param startIndex
- * @param endIndex
- * @return
- */
- public abstract GroovyExpression generateRangeExpression(GroovyExpression parent, int startIndex, int endIndex);
-
- /**
- * Determines if the specified expression is a range method call.
- *
- * @param expr
- * @return
- */
- public abstract boolean isRangeExpression(GroovyExpression expr);
-
- /**
- * Set the start index and end index of a range expression
- *
- * @param expr
- * @param startIndex
- * @param endIndex
- */
- public abstract void setRangeParameters(GroovyExpression expr, int startIndex, int endIndex);
-
- /**
- * If the specified function expression is a range expression, returns the start and end index parameters
- * otherwise returns null.
- *
- * @param expr
- * @return int array with two elements - element 0 is start index, element 1 is end index
- */
- public abstract int[] getRangeParameters(AbstractFunctionExpression expr);
-
- /**
- * Generates an order by expression
- *
- * @param parent
- * @param translatedOrderBy
- * @param isAscending
- * @return
- */
- public abstract GroovyExpression generateOrderByExpression(GroovyExpression parent,
- List<GroovyExpression> translatedOrderBy, boolean isAscending);
-
- /**
- * Determines if specified expression is an order method call
- *
- * @param expr
- * @return
- */
- public boolean isOrderExpression(GroovyExpression expr) {
- if (expr instanceof FunctionCallExpression) {
- FunctionCallExpression functionCallExpression = (FunctionCallExpression) expr;
- if (functionCallExpression.getFunctionName().equals(ORDER_METHOD)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns the Groovy expressions that should be used as the parents when
- * translating an order by expression. This is needed because Gremlin 2 and
- * 3 handle order by expressions very differently.
- *
- */
- public abstract List<GroovyExpression> getOrderFieldParents();
-
- /**
- * Returns the expression that represents an anonymous graph traversal.
- *
- * @return
- */
- public abstract GroovyExpression getAnonymousTraversalExpression();
-
- public boolean isLeafAnonymousTraversalExpression(GroovyExpression expr) {
- if(!(expr instanceof FunctionCallExpression)) {
- return false;
- }
- FunctionCallExpression functionCallExpr = (FunctionCallExpression)expr;
- if(functionCallExpr.getCaller() != null) {
- return false;
- }
- return functionCallExpr.getFunctionName().equals("_") & functionCallExpr.getArguments().size() == 0;
- }
-
- /**
- * Returns an expression representing
- *
- * @return
- */
- public abstract GroovyExpression getFieldInSelect();
-
- /**
- * Generates the expression the serves as the root of the Gremlin query.
- * @param varExpr variable containing the vertices to traverse
- * @return
- */
- protected abstract GroovyExpression initialExpression(GroovyExpression varExpr, GraphPersistenceStrategies s);
-
-
- /**
- * Generates an expression that tests whether the vertex represented by the 'toTest'
- * expression represents an instance of the specified type, checking both the type
- * and super type names.
- *
- * @param s
- * @param typeName
- * @param itRef
- * @return
- */
- protected abstract GroovyExpression typeTestExpression(GraphPersistenceStrategies s, String typeName,
- GroovyExpression vertexExpr);
-
- /**
- /**
- * Generates a sequence of groovy expressions that filter the vertices to only
- * those that match the specified type. If GraphPersistenceStrategies.collectTypeInstancesIntoVar()
- * is set and the gremlin optimizer is disabled, the vertices are put into a variable whose name is generated
- * from the specified IntSequence. The last item in the result will be a graph traversal restricted to only
- * the matching vertices.
- */
- public List<GroovyExpression> generateTypeTestExpression(GraphPersistenceStrategies s, GroovyExpression parent,
- String typeName, IntSequence intSeq) throws AtlasException {
-
- if(AtlasRepositoryConfiguration.isGremlinOptimizerEnabled()) {
- GroovyExpression superTypeAttributeNameExpr = new LiteralExpression(s.superTypeAttributeName());
- GroovyExpression typeNameExpr = new LiteralExpression(typeName);
- GroovyExpression superTypeMatchesExpr = new FunctionCallExpression(TraversalStepType.FILTER, HAS_METHOD, superTypeAttributeNameExpr,
- typeNameExpr);
-
- GroovyExpression typeAttributeNameExpr = new LiteralExpression(s.typeAttributeName());
-
- GroovyExpression typeMatchesExpr = new FunctionCallExpression(TraversalStepType.FILTER, HAS_METHOD, typeAttributeNameExpr,
- typeNameExpr);
- GroovyExpression result = new FunctionCallExpression(TraversalStepType.FILTER, parent, "or", typeMatchesExpr, superTypeMatchesExpr);
- return Collections.singletonList(result);
- }
- else {
- if (s.filterBySubTypes()) {
- return typeTestExpressionUsingInFilter(s, parent, typeName);
- } else if (s.collectTypeInstancesIntoVar()) {
- return typeTestExpressionMultiStep(s, typeName, intSeq);
- } else {
- return typeTestExpressionUsingFilter(s, parent, typeName);
- }
- }
- }
-
- private List<GroovyExpression> typeTestExpressionUsingInFilter(GraphPersistenceStrategies s, GroovyExpression parent,
- final String typeName) throws AtlasException {
- List<GroovyExpression> typeNames = new ArrayList<>();
- typeNames.add(new LiteralExpression(typeName));
-
- Map<TYPE_FILTER, String> filters = new HashMap<TYPE_FILTER, String>() {{
- put(TYPE_FILTER.SUPERTYPE, typeName);
- }};
-
- ImmutableList<String> subTypes = TypeSystem.getInstance().getTypeNames(filters);
-
- if (!subTypes.isEmpty()) {
- for (String subType : subTypes) {
- typeNames.add(new LiteralExpression(subType));
- }
- }
-
- GroovyExpression inFilterExpr = generateHasExpression(s, parent, s.typeAttributeName(), IN_OPERATOR,
- new ListExpression(typeNames), null);
-
- return Collections.singletonList(inFilterExpr);
- }
-
- private List<GroovyExpression> typeTestExpressionMultiStep(GraphPersistenceStrategies s, String typeName,
- IntSequence intSeq) {
-
- String varName = "_var_" + intSeq.next();
- GroovyExpression varExpr = new IdentifierExpression(varName);
- List<GroovyExpression> result = new ArrayList<>();
-
- result.add(newSetVar(varName));
- result.add(fillVarWithTypeInstances(s, typeName, varName));
- result.add(fillVarWithSubTypeInstances(s, typeName, varName));
- result.add(initialExpression(varExpr, s));
-
- return result;
- }
-
- private GroovyExpression newSetVar(String varName) {
- GroovyExpression castExpr = new TypeCoersionExpression(new ListExpression(), SET_CLASS);
- return new VariableAssignmentExpression(varName, castExpr);
- }
-
- private GroovyExpression fillVarWithTypeInstances(GraphPersistenceStrategies s, String typeName, String fillVar) {
- GroovyExpression graphExpr = getAllVerticesExpr();
- GroovyExpression typeAttributeNameExpr = new LiteralExpression(s.typeAttributeName());
- GroovyExpression typeNameExpr = new LiteralExpression(typeName);
- GroovyExpression hasExpr = new FunctionCallExpression(graphExpr, HAS_METHOD, typeAttributeNameExpr, typeNameExpr);
- GroovyExpression fillExpr = new FunctionCallExpression(hasExpr, FILL_METHOD, new IdentifierExpression(fillVar));
- return fillExpr;
- }
-
- private GroovyExpression fillVarWithSubTypeInstances(GraphPersistenceStrategies s, String typeName,
- String fillVar) {
- GroovyExpression graphExpr = getAllVerticesExpr();
- GroovyExpression superTypeAttributeNameExpr = new LiteralExpression(s.superTypeAttributeName());
- GroovyExpression typeNameExpr = new LiteralExpression(typeName);
- GroovyExpression hasExpr = new FunctionCallExpression(graphExpr, HAS_METHOD, superTypeAttributeNameExpr, typeNameExpr);
- GroovyExpression fillExpr = new FunctionCallExpression(hasExpr, FILL_METHOD, new IdentifierExpression(fillVar));
- return fillExpr;
- }
-
-
- private List<GroovyExpression> typeTestExpressionUsingFilter(GraphPersistenceStrategies s, GroovyExpression parent,
- String typeName) {
- GroovyExpression itExpr = getItVariable();
- GroovyExpression typeTestExpr = typeTestExpression(s, typeName, itExpr);
- GroovyExpression closureExpr = new ClosureExpression(typeTestExpr);
- GroovyExpression filterExpr = new FunctionCallExpression(parent, FILTER_METHOD, closureExpr);
- return Collections.singletonList(filterExpr);
- }
-
- /**
- * Generates an expression which checks whether the vertices in the query have
- * a field with the given name.
- *
- * @param parent
- * @param fieldName
- * @return
- */
- public GroovyExpression generateUnaryHasExpression(GroovyExpression parent, String fieldName) {
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, HAS_METHOD, new LiteralExpression(fieldName));
- }
-
- /**
- * Generates a path expression
- *
- * @param parent
- * @return
- */
- public GroovyExpression generatePathExpression(GroovyExpression parent) {
- return new FunctionCallExpression(TraversalStepType.MAP_TO_VALUE, parent, PATH_METHOD);
- }
-
- /**
- * Generates the emit expression used in loop expressions.
- * @param s
- * @param dataType
- * @return
- */
- protected GroovyExpression generateLoopEmitExpression(GraphPersistenceStrategies s, IDataType dataType) {
- return typeTestExpression(s, dataType.getName(), getCurrentObjectExpression());
- }
-
- /**
- * Generates an alias expression
- *
- * @param parent
- * @param alias
- * @return
- */
- public GroovyExpression generateAliasExpression(GroovyExpression parent, String alias) {
- return new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, parent, AS_METHOD, new LiteralExpression(alias));
- }
-
- /**
- * Generates an expression that gets the vertices adjacent to the vertex in 'parent'
- * in the specified direction.
- *
- * @param parent
- * @param dir
- * @return
- */
- public GroovyExpression generateAdjacentVerticesExpression(GroovyExpression parent, AtlasEdgeDirection dir) {
- return new FunctionCallExpression(TraversalStepType.FLAT_MAP_TO_ELEMENTS, parent, getGremlinFunctionName(dir));
- }
-
- private String getGremlinFunctionName(AtlasEdgeDirection dir) {
- switch(dir) {
- case IN:
- return "in";
- case OUT:
- return "out";
- case BOTH:
- return "both";
- default:
- throw new RuntimeException("Unknown Atlas Edge Direction: " + dir);
- }
- }
-
- /**
- * Generates an expression that gets the vertices adjacent to the vertex in 'parent'
- * in the specified direction, following only edges with the given label.
- *
- * @param parent
- * @param dir
- * @return
- */
- public GroovyExpression generateAdjacentVerticesExpression(GroovyExpression parent, AtlasEdgeDirection dir,
- String label) {
- return new FunctionCallExpression(TraversalStepType.FLAT_MAP_TO_ELEMENTS, parent, getGremlinFunctionName(dir), new LiteralExpression(label));
- }
-
- /**
- * Generates an arithmetic expression, e.g. a + b
- *
- */
- public GroovyExpression generateArithmeticExpression(GroovyExpression left, String operator,
- GroovyExpression right) throws AtlasException {
- ArithmeticOperator op = ArithmeticOperator.lookup(operator);
- return new ArithmeticExpression(left, op, right);
- }
-
- public abstract GroovyExpression generateGroupByExpression(GroovyExpression parent, GroovyExpression groupByExpression, GroovyExpression aggregationFunction);
-
- protected GroovyExpression getItVariable() {
- return new IdentifierExpression(IT_VARIABLE);
- }
-
- protected GroovyExpression getAllVerticesExpr() {
- GroovyExpression gExpr = getGraphExpression();
- return new FunctionCallExpression(TraversalStepType.START, gExpr, V_METHOD);
- }
-
- protected IdentifierExpression getGraphExpression() {
- return new IdentifierExpression(TraversalStepType.SOURCE, G_VARIABLE);
- }
-
-
- protected GroovyExpression getCurrentObjectExpression() {
- return new FieldExpression(getItVariable(), OBJECT_FIELD);
- }
-
- //assumes cast already performed
- public GroovyExpression generateCountExpression(GroovyExpression itExpr) {
- GroovyExpression collectionExpr = new CastExpression(itExpr,"Collection");
- return new FunctionCallExpression(collectionExpr, "size");
- }
-
- public GroovyExpression generateMinExpression(GroovyExpression itExpr, GroovyExpression mapFunction) {
- return getAggregrationExpression(itExpr, mapFunction, "min");
- }
-
- public GroovyExpression generateMaxExpression(GroovyExpression itExpr, GroovyExpression mapFunction) {
- return getAggregrationExpression(itExpr, mapFunction, "max");
- }
-
- public GroovyExpression generateSumExpression(GroovyExpression itExpr, GroovyExpression mapFunction) {
- return getAggregrationExpression(itExpr, mapFunction, "sum");
- }
-
- private GroovyExpression getAggregrationExpression(GroovyExpression itExpr,
- GroovyExpression mapFunction, String functionName) {
- GroovyExpression collectionExpr = new CastExpression(itExpr,"Collection");
- ClosureExpression collectFunction = new ClosureExpression(mapFunction);
- GroovyExpression transformedList = new FunctionCallExpression(collectionExpr, "collect", collectFunction);
- return new FunctionCallExpression(transformedList, functionName);
- }
-
- public GroovyExpression getClosureArgumentValue() {
- return getItVariable();
- }
-
- /**
- * Specifies the parent to use when translating the select list in
- * a group by statement.
- *
- * @return
- */
- public abstract GroovyExpression getGroupBySelectFieldParent();
-
- public GroovyExpression generateFillExpression(GroovyExpression parent, GroovyExpression variable) {
- return new FunctionCallExpression(TraversalStepType.END,parent , "fill", variable);
- }
-
- /**
- * Generates an anonymous graph traversal initialized with the specified value. In Gremlin 3, we need
- * to use a different syntax for this when the object is a map, so that information needs to be provided
- * to this method so that the correct syntax is used.
- *
- * @param isMap true if the value contains Map instances, false if it contains Vertex instances
- * @param valueCollection the source objects to start the traversal from.
- */
- public abstract GroovyExpression generateSeededTraversalExpresssion(boolean isMap, GroovyExpression valueCollection);
-
- /**
- * Returns the current value of the traverser. This is used when generating closure expressions that
- * need to operate on the current value in the graph graversal.
- *
- * @param traverser
- * @return
- */
- public abstract GroovyExpression getCurrentTraverserObject(GroovyExpression traverser);
-
- /**
- * Generates an expression that transforms the current value of the traverser by
- * applying the function specified
- *
- * @param parent
- * @param closureExpression
- * @return
- */
- public abstract GroovyExpression generateMapExpression(GroovyExpression parent, ClosureExpression closureExpression);
-
- /**
- * Returns whether a select statement generates a map (or Gremlin 2 "Row") when it contains the specified
- * number of aliases.
- *
- */
- public abstract boolean isSelectGeneratesMap(int aliasCount);
-
- /**
- * Generates an expression to get the value of the value from the row map
- * generated by select() with the specified key.
- *
- */
- public abstract GroovyExpression generateGetSelectedValueExpression(LiteralExpression key,
- GroovyExpression rowMapExpr);
-
- public GroovyExpression removeExtraMapFromPathInResult(GroovyExpression parent) {
- GroovyExpression listItem = getItVariable();
- GroovyExpression tailExpr = new FunctionCallExpression(listItem, "tail");
- return new FunctionCallExpression(parent, "collect", new ClosureExpression(tailExpr));
-
- }
-
- /**
- * Generates a toList expression to execute the gremlin query and
- * store the result in a new list.
- *
- * @param expr
- * @return
- */
- public GroovyExpression generateToListExpression(GroovyExpression expr) {
- return new FunctionCallExpression(TraversalStepType.END, expr, "toList");
- }
-
- /**
- * Finds aliases that absolutely must be brought along with this expression into
- * the output expression and cannot just be recreated there. For example, in the
- * Gremlin 2 loop expression, the loop semantics break of the alias is simply recreated
- * in the output expression.
- * @param expr
- * @return
- */
- public abstract List<String> getAliasesRequiredByExpression(GroovyExpression expr);
-
-
- /**
- * Checks if the given expression is an alias expression, and if so
- * returns the alias from the expression. Otherwise, null is
- * returned.
- */
- public String getAliasNameIfRelevant(GroovyExpression expr) {
- if(!(expr instanceof FunctionCallExpression)) {
- return null;
- }
- FunctionCallExpression fc = (FunctionCallExpression)expr;
- if(! fc.getFunctionName().equals(AS_METHOD)) {
- return null;
- }
- LiteralExpression aliasName = (LiteralExpression)fc.getArguments().get(0);
- return aliasName.getValue().toString();
-
- }
-
- public abstract boolean isRepeatExpression(GroovyExpression expr);
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/0877e47c/repository/src/main/java/org/apache/atlas/gremlin/optimizer/AliasFinder.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/optimizer/AliasFinder.java b/repository/src/main/java/org/apache/atlas/gremlin/optimizer/AliasFinder.java
deleted file mode 100644
index 3e6c39a..0000000
--- a/repository/src/main/java/org/apache/atlas/gremlin/optimizer/AliasFinder.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-package org.apache.atlas.gremlin.optimizer;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.atlas.groovy.AbstractFunctionExpression;
-import org.apache.atlas.groovy.FunctionCallExpression;
-import org.apache.atlas.groovy.GroovyExpression;
-import org.apache.atlas.groovy.LiteralExpression;
-import org.apache.atlas.groovy.TraversalStepType;
-
-/**
- * Finds all aliases in the expression.
- */
-public class AliasFinder implements CallHierarchyVisitor {
-
- private List<LiteralExpression> foundAliases = new ArrayList<>();
-
- //Whether a final alias is needed. A final alias is needed
- //if there are transformation steps after the last alias in
- //the expression. We initialize this to false since a final
- //alias is not needed if there are no aliases.
- private boolean finalAliasNeeded = false;
-
- @Override
- public boolean preVisitFunctionCaller(AbstractFunctionExpression expr) {
- return true;
- }
-
- @Override
- public void visitNonFunctionCaller(GroovyExpression expr) {
-
- }
-
- @Override
- public void visitNullCaller() {
-
- }
-
- private static final Set<TraversalStepType> TRANSFORMATION_STEP_TYPES = new HashSet<>(Arrays.asList(
- TraversalStepType.MAP_TO_ELEMENT,
- TraversalStepType.MAP_TO_VALUE,
- TraversalStepType.FLAT_MAP_TO_ELEMENTS,
- TraversalStepType.FLAT_MAP_TO_VALUES,
- TraversalStepType.BARRIER,
- TraversalStepType.NONE));
-
-
- @Override
- public boolean postVisitFunctionCaller(AbstractFunctionExpression functionCall) {
-
- if (functionCall instanceof FunctionCallExpression) {
- FunctionCallExpression expr = (FunctionCallExpression)functionCall;
- if (expr.getType() == TraversalStepType.SIDE_EFFECT && expr.getFunctionName().equals("as")) {
- //We found an alias. This is currently the last expression we've seen
- //in our traversal back up the expression tree, so at this point a final
- //alias is not needed.
- LiteralExpression aliasNameExpr = (LiteralExpression)expr.getArguments().get(0);
- foundAliases.add(aliasNameExpr);
- finalAliasNeeded=false;
- }
- }
-
- if(TRANSFORMATION_STEP_TYPES.contains(functionCall.getType())) {
- //This step changes the value of the traverser. Now, a final alias
- //needs to be added.
- if(!foundAliases.isEmpty()) {
- finalAliasNeeded = true;
- }
- }
-
- return true;
- }
-
- public List<LiteralExpression> getAliases() {
- return foundAliases;
- }
-
- public boolean isFinalAliasNeeded() {
-
- return finalAliasNeeded;
- }
-}
http://git-wip-us.apache.org/repos/asf/atlas/blob/0877e47c/repository/src/main/java/org/apache/atlas/gremlin/optimizer/CallHierarchyVisitor.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/optimizer/CallHierarchyVisitor.java b/repository/src/main/java/org/apache/atlas/gremlin/optimizer/CallHierarchyVisitor.java
deleted file mode 100644
index 6089353..0000000
--- a/repository/src/main/java/org/apache/atlas/gremlin/optimizer/CallHierarchyVisitor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-package org.apache.atlas.gremlin.optimizer;
-
-import org.apache.atlas.groovy.AbstractFunctionExpression;
-import org.apache.atlas.groovy.GroovyExpression;
-
-/**
- * Call back interface for visiting the call hierarchy of a function call.
- */
-public interface CallHierarchyVisitor {
-
- /**
- * Visits a function expression before the visit to its caller.
- *
- * @param expr
- *
- * @return false to terminate the recursion
- */
- boolean preVisitFunctionCaller(AbstractFunctionExpression expr);
-
- /**
- * Called when a caller that is not an instance of
- * AbstractFunctionExpression is found. This indicates that the deepest
- * point in the call hierarchy has been reached.
- *
- *
- */
- void visitNonFunctionCaller(GroovyExpression expr);
-
- /**
- * Called when a null caller is found (this happens for static/user-defined
- * functions). This indicates that the deepest point in the call hierarchy
- * has been reached.
- *
- */
- void visitNullCaller();
-
- /**
- * Visits a function expression after the visit to its caller.
- *
- * @param expr
- *
- * @return false to terminate the recursion
- */
- boolean postVisitFunctionCaller(AbstractFunctionExpression functionCall);
-}
http://git-wip-us.apache.org/repos/asf/atlas/blob/0877e47c/repository/src/main/java/org/apache/atlas/gremlin/optimizer/ExpandAndsOptimization.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/optimizer/ExpandAndsOptimization.java b/repository/src/main/java/org/apache/atlas/gremlin/optimizer/ExpandAndsOptimization.java
deleted file mode 100644
index d8ecd07..0000000
--- a/repository/src/main/java/org/apache/atlas/gremlin/optimizer/ExpandAndsOptimization.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-package org.apache.atlas.gremlin.optimizer;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.atlas.gremlin.GremlinExpressionFactory;
-import org.apache.atlas.groovy.AbstractFunctionExpression;
-import org.apache.atlas.groovy.FunctionCallExpression;
-import org.apache.atlas.groovy.GroovyExpression;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Optimizer that pulls has expressions out of an 'and' expression.
- * <p>
- * For example:
- * <pre class=code>
- * g.V().and(has('x'),has('y') </pre>
- * <p>
- * is optimized to:
- * <pre class=code>
- * g.V().has('x').has('y') </pre>
- * <p>
- * There are certain cases where it is not safe to move an expression out
- * of the 'and'. For example, in the expression
- * <pre class=code>
- * g.V().and(has('x').out('y'),has('z')) </pre>
- * <p>
- * has('x').out('y') cannot be moved out of the 'and', since it changes the value of the traverser.
- * <p>
- * At this time, the ExpandAndsOptimizer is not able to handle this scenario, so we don't extract
- * that expression. In this case, the result is:
- * <pre class=code>
- * g.V().has('z').and(has('x').out('y')) </pre>
- * <p>
- * The optimizer will call ExpandAndsOptimization recursively on the children, so
- * there is no need to recursively update the children here.
- *
- */
-public class ExpandAndsOptimization implements GremlinOptimization {
-
- private static final Logger logger_ = LoggerFactory.getLogger(ExpandAndsOptimization.class);
-
-
- private final GremlinExpressionFactory factory;
-
- public ExpandAndsOptimization(GremlinExpressionFactory factory) {
- this.factory = factory;
- }
-
- @Override
- public boolean appliesTo(GroovyExpression expr, OptimizationContext contxt) {
- return expr instanceof FunctionCallExpression && ((FunctionCallExpression)expr).getFunctionName().equals("and");
- }
-
- /**
- * Expands the given and expression. There is no need to recursively
- * expand the children here. This method is called recursively by
- * GremlinQueryOptimier on the children.
- *
- */
- @Override
- public GroovyExpression apply(GroovyExpression expr, OptimizationContext context) {
-
- FunctionCallExpression exprAsFunction = (FunctionCallExpression)expr;
- GroovyExpression result = exprAsFunction.getCaller();
-
- List<GroovyExpression> nonExtractableArguments = new ArrayList<>();
- for(GroovyExpression argument : exprAsFunction.getArguments()) {
-
- if (GremlinQueryOptimizer.isExtractable(argument)) {
- //Set the caller of the deepest expression in the call hierarchy
- //of the argument to point to the current result.
- //For example, if result is "g.V()" and the updatedArgument is "has('x').has('y')",
- //updatedArgument would be a tree like this:
- //
- // has('y')
- // /
- // / caller
- // |/_
- // has('x')
- // /
- // / caller
- // |/_
- // (null)
- //
- //We would set the caller of has('x') to be g.V(), so result would become g.V().has('x').has('y').
- //
- // Note: This operation is currently done by making a copy of the argument tree. That should
- // be changed.
- result = GremlinQueryOptimizer.copyWithNewLeafNode(
- (AbstractFunctionExpression) argument, result);
- } else {
- logger_.warn("Found non-extractable argument '{}' in the 'and' expression '{}'",argument.toString(), expr.toString());
- nonExtractableArguments.add(argument);
- }
- }
-
- if (!nonExtractableArguments.isEmpty()) {
- //add a final 'and' call with the arguments that could not be extracted
- result = factory.generateLogicalExpression(result, "and", nonExtractableArguments);
- }
- return result;
- }
-
- @Override
- public boolean isApplyRecursively() {
- return true;
- }
-}