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 <[email protected]> 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 <[email protected]> --- 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")) ||
