You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ni...@apache.org on 2020/05/14 10:30:08 UTC

[atlas] 02/02: ATLAS-3783 : DSL query search should return results for both the relationship edge directions

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

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

commit c08c9f382b88570d3bea1fb66937142b2f719f56
Author: chaitali borole <ch...@cloudera.com>
AuthorDate: Wed May 6 15:57:59 2020 +0530

    ATLAS-3783 : DSL query search should return results for both the relationship edge directions
    
    Signed-off-by: nixonrodrigues <ni...@apache.org>
---
 docs/src/documents/Search/SearchAdvanced.md              | 12 ++++++++++++
 .../org/apache/atlas/query/GremlinQueryComposer.java     | 16 ++++++++++++++--
 .../java/org/apache/atlas/query/IdentifierHelper.java    | 10 ++++++++--
 .../src/main/java/org/apache/atlas/query/Lookup.java     |  3 +++
 .../java/org/apache/atlas/query/RegistryBasedLookup.java | 16 ++++++++++++++++
 .../test/java/org/apache/atlas/query/DSLQueriesTest.java |  2 ++
 .../org/apache/atlas/query/GremlinQueryComposerTest.java |  8 +++++++-
 7 files changed, 62 insertions(+), 5 deletions(-)

diff --git a/docs/src/documents/Search/SearchAdvanced.md b/docs/src/documents/Search/SearchAdvanced.md
index 544c85a..46be142 100644
--- a/docs/src/documents/Search/SearchAdvanced.md
+++ b/docs/src/documents/Search/SearchAdvanced.md
@@ -98,6 +98,18 @@ Example: To retrieve _DB_ whose name starts with _R_ followed by has any 3 chara
 {`DB where name like "R???rt?*"`}
 </SyntaxHighlighter>
 
+Example: To find all the columns in a Table.
+
+<SyntaxHighlighter wrapLines={true} language="html" style={theme.dark}>
+{`Column where table.name="sales_fact"`}
+</SyntaxHighlighter>
+
+Example: To find all the Tables for a column.
+
+<SyntaxHighlighter wrapLines={true} language="html" style={theme.dark}>
+{`Table where columns.name="sales"`}
+</SyntaxHighlighter>
+
 
 ### Using Date Literals
 Dates used in literals need to be specified using the ISO 8601 format.
diff --git a/repository/src/main/java/org/apache/atlas/query/GremlinQueryComposer.java b/repository/src/main/java/org/apache/atlas/query/GremlinQueryComposer.java
index 04b1775..801e898 100644
--- a/repository/src/main/java/org/apache/atlas/query/GremlinQueryComposer.java
+++ b/repository/src/main/java/org/apache/atlas/query/GremlinQueryComposer.java
@@ -49,6 +49,8 @@ import java.util.stream.Stream;
 
 import static org.apache.atlas.model.discovery.SearchParameters.ALL_CLASSIFICATIONS;
 import static org.apache.atlas.model.discovery.SearchParameters.NO_CLASSIFICATIONS;
+import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.IN;
+import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.OUT;
 
 public class GremlinQueryComposer {
     private static final Logger LOG                 = LoggerFactory.getLogger(GremlinQueryComposer.class);
@@ -214,7 +216,12 @@ public class GremlinQueryComposer {
 
         if (org != null && org.isReferredType()) {
             add(GremlinClause.DEDUP);
-            add(GremlinClause.IN, org.getEdgeLabel());
+            if (org.getEdgeDirection() != null) {
+                GremlinClause gremlinClauseForEdgeLabel = org.getEdgeDirection().equals(IN) ? GremlinClause.OUT : GremlinClause.IN;
+                add(gremlinClauseForEdgeLabel, org.getEdgeLabel());
+            } else {
+                add(GremlinClause.OUT, org.getEdgeLabel());
+            }
             context.registerActive(currentType);
         }
     }
@@ -575,7 +582,12 @@ public class GremlinQueryComposer {
 
     private boolean introduceType(IdentifierHelper.Info ia) {
         if (ia.isReferredType()) {
-            add(GremlinClause.OUT, ia.getEdgeLabel());
+            if (ia.getEdgeDirection() != null) {
+                GremlinClause gremlinClauseForEdgeLabel = ia.getEdgeDirection().equals(OUT) ? GremlinClause.OUT : GremlinClause.IN;
+                add(gremlinClauseForEdgeLabel, ia.getEdgeLabel());
+            } else {
+                add(GremlinClause.OUT, ia.getEdgeLabel());
+            }
             context.registerActive(ia);
         }
 
diff --git a/repository/src/main/java/org/apache/atlas/query/IdentifierHelper.java b/repository/src/main/java/org/apache/atlas/query/IdentifierHelper.java
index 6ab61e1..129c203 100644
--- a/repository/src/main/java/org/apache/atlas/query/IdentifierHelper.java
+++ b/repository/src/main/java/org/apache/atlas/query/IdentifierHelper.java
@@ -21,6 +21,7 @@ package org.apache.atlas.query;
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.type.AtlasBusinessMetadataType;
+import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
 import org.apache.atlas.type.AtlasType;
 import org.apache.commons.lang.StringUtils;
 
@@ -126,6 +127,7 @@ public class IdentifierHelper {
         private String   typeName;
         private String   attributeName;
         private boolean  isPrimitive;
+        private AtlasRelationshipEdgeDirection edgeDirection;
         private String   edgeLabel;
         private boolean  introduceType;
         private boolean  hasSubtypes;
@@ -157,7 +159,7 @@ public class IdentifierHelper {
                     updateSubTypes(lookup, context);
                 }
             } catch (NullPointerException ex) {
-                context.getErrorList().add(ex.getMessage());
+                context.getErrorList().add("NullPointerException");
             }
         }
 
@@ -178,6 +180,7 @@ public class IdentifierHelper {
 
         private void updateEdgeInfo(org.apache.atlas.query.Lookup lookup, GremlinQueryComposer.Context context) {
             if (!isPrimitive && !isTrait && typeName != attributeName) {
+                edgeDirection = lookup.getRelationshipEdgeDirection(context, attributeName);
                 edgeLabel = lookup.getRelationshipEdgeLabel(context, attributeName);
                 typeName = lookup.getTypeFromEdge(context, attributeName);
             }
@@ -225,7 +228,6 @@ public class IdentifierHelper {
             setIsDate(lookup, context, isPrimitive, attributeName);
             setIsNumeric(lookup, context, isPrimitive, attributeName);
         }
-
         private String getDefaultQualifiedNameForSinglePartName(GremlinQueryComposer.Context context, String s) {
             String qn = context.getTypeNameFromAlias(s);
             if (StringUtils.isEmpty(qn) && SelectClauseComposer.isKeyword(s)) {
@@ -273,6 +275,10 @@ public class IdentifierHelper {
             return attributeName;
         }
 
+        public AtlasRelationshipEdgeDirection getEdgeDirection() {
+            return edgeDirection;
+        }
+
         public String getEdgeLabel() {
             return edgeLabel;
         }
diff --git a/repository/src/main/java/org/apache/atlas/query/Lookup.java b/repository/src/main/java/org/apache/atlas/query/Lookup.java
index 3c192d8..d4567db 100644
--- a/repository/src/main/java/org/apache/atlas/query/Lookup.java
+++ b/repository/src/main/java/org/apache/atlas/query/Lookup.java
@@ -20,6 +20,7 @@ package org.apache.atlas.query;
 
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
 
 public interface Lookup {
     AtlasType getType(String typeName) throws AtlasBaseException;
@@ -30,6 +31,8 @@ public interface Lookup {
 
     String getRelationshipEdgeLabel(GremlinQueryComposer.Context context, String attributeName);
 
+    AtlasRelationshipEdgeDirection getRelationshipEdgeDirection(GremlinQueryComposer.Context context, String attributeName);
+
     boolean hasAttribute(GremlinQueryComposer.Context context, String typeName);
 
     boolean doesTypeHaveSubTypes(GremlinQueryComposer.Context context);
diff --git a/repository/src/main/java/org/apache/atlas/query/RegistryBasedLookup.java b/repository/src/main/java/org/apache/atlas/query/RegistryBasedLookup.java
index 2b34abf..d536900 100644
--- a/repository/src/main/java/org/apache/atlas/query/RegistryBasedLookup.java
+++ b/repository/src/main/java/org/apache/atlas/query/RegistryBasedLookup.java
@@ -22,6 +22,7 @@ import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
 import org.apache.atlas.type.*;
+import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
 import org.apache.commons.lang.StringUtils;
 
 import java.util.*;
@@ -122,6 +123,21 @@ class RegistryBasedLookup implements Lookup {
     }
 
     @Override
+    public AtlasRelationshipEdgeDirection getRelationshipEdgeDirection(GremlinQueryComposer.Context context, String attributeName) {
+        AtlasEntityType entityType  = context.getActiveEntityType();
+        AtlasStructType.AtlasAttribute attribute = null;
+        AtlasRelationshipEdgeDirection ret = null;
+
+        if (entityType != null) {
+            attribute = entityType.getRelationshipAttribute(attributeName, null);
+            if (attribute != null) {
+                ret = attribute.getRelationshipEdgeDirection();
+            }
+        }
+        return ret;
+    }
+
+    @Override
     public boolean hasAttribute(GremlinQueryComposer.Context context, String typeName) {
         AtlasEntityType entityType = context.getActiveEntityType();
 
diff --git a/repository/src/test/java/org/apache/atlas/query/DSLQueriesTest.java b/repository/src/test/java/org/apache/atlas/query/DSLQueriesTest.java
index d4db141..5ace379 100644
--- a/repository/src/test/java/org/apache/atlas/query/DSLQueriesTest.java
+++ b/repository/src/test/java/org/apache/atlas/query/DSLQueriesTest.java
@@ -205,6 +205,8 @@ public class DSLQueriesTest extends BasicTestSetup {
     @DataProvider(name = "basicProvider")
     private Object[][] basicQueries() {
         return new Object[][]{
+                {"hive_column where table.name = \"sales_fact_daily_mv\"", 4},
+                {"hive_table where columns.name = \"app_id\"", 2},
                 {"from hive_db", 3},
                 {"hive_db", 3},
                 {"hive_db as d select d", 3},
diff --git a/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java b/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
index 6f4df88..959aa11 100644
--- a/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
+++ b/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
@@ -24,6 +24,7 @@ import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.query.antlr4.AtlasDSLParser;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasStructType;
+import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.commons.lang.StringUtils;
@@ -36,7 +37,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
-
+import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.OUT;
 public class GremlinQueryComposerTest {
     @Test
     public void classification() {
@@ -482,6 +483,11 @@ public class GremlinQueryComposerTest {
         }
 
         @Override
+        public AtlasRelationshipEdgeDirection getRelationshipEdgeDirection(GremlinQueryComposer.Context context, String attributeName) {
+            return OUT;
+        }
+
+        @Override
         public boolean hasAttribute(GremlinQueryComposer.Context context, String attributeName) {
             return (context.getActiveTypeName().equals("Table") && attributeName.equals("db")) ||
                     (context.getActiveTypeName().equals("Table") && attributeName.equals("columns")) ||