Repository: atlas Updated Branches: refs/heads/master 1fee4a5b6 -> c35f82ca1
http://git-wip-us.apache.org/repos/asf/atlas/blob/c35f82ca/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java ---------------------------------------------------------------------- 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 5b394cb..84fe631 100644 --- a/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java +++ b/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java @@ -17,7 +17,9 @@ */ package org.apache.atlas.query; +import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.exception.AtlasBaseException; +import org.apache.atlas.model.TypeCategory; import org.apache.atlas.query.antlr4.AtlasDSLParser; import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasType; @@ -26,26 +28,21 @@ import org.apache.commons.lang.StringUtils; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import java.util.ArrayList; -import java.util.List; - import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; public class GremlinQueryComposerTest { - private List<String> errorList = new ArrayList<>(); - @Test public void classification() { - String expected = "g.V().has('__traitNames', within('PII')).limit(25).toList()"; + String expected = "g.V().has('__traitNames', within('PII')).limit(local, 25).limit(25).toList()"; verify("PII", expected); } @Test() public void dimension() { - String expected = "g.V().has('__typeName', 'Table').has('__traitNames', within('Dimension')).limit(25).toList()"; + String expected = "g.V().has('__typeName', 'Table').has('__traitNames', within('Dimension')).limit(local, 25).limit(25).toList()"; verify("Table isa Dimension", expected); verify("Table is Dimension", expected); verify("Table where Table is Dimension", expected); @@ -53,58 +50,59 @@ public class GremlinQueryComposerTest { @Test public void fromDB() { - verify("from DB", "g.V().has('__typeName', 'DB').limit(25).toList()"); - verify("from DB limit 10", "g.V().has('__typeName', 'DB').limit(10).toList()"); - verify("DB limit 10", "g.V().has('__typeName', 'DB').limit(10).toList()"); + String expected10 = "g.V().has('__typeName', 'DB').limit(local, 10).limit(10).toList()"; + verify("from DB", "g.V().has('__typeName', 'DB').limit(local, 25).limit(25).toList()"); + verify("from DB limit 10", expected10); + verify("DB limit 10", expected10); } @Test public void DBHasName() { - String expected = "g.V().has('__typeName', 'DB').has('DB.name').limit(25).toList()"; + String expected = "g.V().has('__typeName', 'DB').has('DB.name').limit(local, 25).limit(25).toList()"; verify("DB has name", expected); verify("DB where DB has name", expected); } @Test public void DBasD() { - verify("DB as d", "g.V().has('__typeName', 'DB').as('d').limit(25).toList()"); + verify("DB as d", "g.V().has('__typeName', 'DB').as('d').limit(local, 25).limit(25).toList()"); } @Test public void DBasDSelect() { String expected = "def f(r){ t=[['d.name','d.owner']]; r.each({t.add([it.value('DB.name'),it.value('DB.owner')])}); t.unique(); }; " + "f(g.V().has('__typeName', 'DB').as('d')"; - verify("DB as d select d.name, d.owner", expected + ".limit(25).toList())"); - verify("DB as d select d.name, d.owner limit 10", expected + ".limit(10).toList())"); - verify("DB as d select d","def f(r){ r }; f(g.V().has('__typeName', 'DB').as('d').limit(25).toList())"); + verify("DB as d select d.name, d.owner", expected + ".limit(local, 25).limit(25).toList())"); + verify("DB as d select d.name, d.owner limit 10", expected + ".limit(local, 10).limit(10).toList())"); + verify("DB as d select d","def f(r){ r }; f(g.V().has('__typeName', 'DB').as('d').limit(local, 25).limit(25).toList())"); } @Test public void tableSelectColumns() { - String exMain = "g.V().has('__typeName', 'Table').out('__Table.columns').limit(10).toList()"; + String exMain = "g.V().has('__typeName', 'Table').out('__Table.columns').limit(local, 10).limit(10).toList()"; String exSel = "def f(r){ r }"; String exSel1 = "def f(r){ t=[['db.name']]; r.each({t.add([it.value('DB.name')])}); t.unique(); }"; verify("Table select columns limit 10", getExpected(exSel, exMain)); - String exMain2 = "g.V().has('__typeName', 'Table').out('__Table.db').limit(25).toList()"; + String exMain2 = "g.V().has('__typeName', 'Table').out('__Table.db').limit(local, 25).limit(25).toList()"; verify("Table select db", getExpected(exSel, exMain2)); - String exMain3 = "g.V().has('__typeName', 'Table').out('__Table.db').limit(25).toList()"; + String exMain3 = "g.V().has('__typeName', 'Table').out('__Table.db').limit(local, 25).limit(25).toList()"; verify("Table select db.name", getExpected(exSel1, exMain3)); } @Test public void valueArray() { - verify("DB where owner = ['hdfs', 'anon']", "g.V().has('__typeName', 'DB').has('DB.owner', within('hdfs','anon')).limit(25).toList()"); - verify("DB owner = ['hdfs', 'anon']", "g.V().has('__typeName', 'DB').has('DB.owner', within('hdfs','anon')).limit(25).toList()"); - verify("hive_db as d owner = ['hdfs', 'anon']", "g.V().has('__typeName', 'hive_db').as('d').has('hive_db.owner', within('hdfs','anon')).limit(25).toList()"); + verify("DB where owner = ['hdfs', 'anon']", "g.V().has('__typeName', 'DB').has('DB.owner', within('hdfs','anon')).limit(local, 25).limit(25).toList()"); + verify("DB owner = ['hdfs', 'anon']", "g.V().has('__typeName', 'DB').has('DB.owner', within('hdfs','anon')).limit(local, 25).limit(25).toList()"); + verify("hive_db as d owner = ['hdfs', 'anon']", "g.V().has('__typeName', 'hive_db').as('d').has('hive_db.owner', within('hdfs','anon')).limit(local, 25).limit(25).toList()"); } @Test public void groupByMin() { verify("from DB groupby (owner) select min(name) orderby name limit 2", "def f(l){ t=[['min(name)']]; l.get(0).each({k,r -> L:{ def min=r.min({it.value('DB.name')}).value('DB.name'); t.add([min]); } }); t; }; " + - "f(g.V().has('__typeName', 'DB').group().by('DB.owner').limit(2).toList())"); + "f(g.V().has('__typeName', 'DB').group().by('DB.owner').limit(local, 2).limit(2).toList())"); } @Test @@ -113,29 +111,28 @@ public class GremlinQueryComposerTest { "def f(l){ h=[['name','owner','clusterName']]; t=[]; " + "l.get(0).each({k,r -> L:{ r.each({t.add([it.value('Table.name'),it.value('Table.owner'),it.value('Table.clusterName')])}) } }); " + "h.plus(t.unique().sort{a,b -> a[0] <=> b[0]}); }; " + - "f(g.V().has('__typeName', 'Table').group().by('Table.owner').limit(25).toList())"); + "f(g.V().has('__typeName', 'Table').group().by('Table.owner').limit(local, 25).limit(25).toList())"); } @Test public void DBAsDSelectLimit() { - verify("from DB limit 5", "g.V().has('__typeName', 'DB').limit(5).toList()"); - verify("from DB limit 5 offset 2", "g.V().has('__typeName', 'DB').range(2, 2 + 5).toList()"); + verify("from DB limit 5", "g.V().has('__typeName', 'DB').limit(local, 5).limit(5).toList()"); + verify("from DB limit 5 offset 2", "g.V().has('__typeName', 'DB').range(local, 2, 2 + 5).range(2, 2 + 5).toList()"); } @Test public void DBOrderBy() { - String expected = "g.V().has('__typeName', 'DB').order().by('DB.name').limit(25).toList()"; + String expected = "g.V().has('__typeName', 'DB').order().by('DB.name').limit(local, 25).limit(25).toList()"; verify("DB orderby name", expected); verify("from DB orderby name", expected); - verify("from DB as d orderby d.owner limit 3", "g.V().has('__typeName', 'DB').as('d').order().by('DB.owner').limit(3).toList()"); - verify("DB as d orderby d.owner limit 3", "g.V().has('__typeName', 'DB').as('d').order().by('DB.owner').limit(3).toList()"); - + verify("from DB as d orderby d.owner limit 3", "g.V().has('__typeName', 'DB').as('d').order().by('DB.owner').limit(local, 3).limit(3).toList()"); + verify("DB as d orderby d.owner limit 3", "g.V().has('__typeName', 'DB').as('d').order().by('DB.owner').limit(local, 3).limit(3).toList()"); String exSel = "def f(r){ t=[['d.name','d.owner']]; r.each({t.add([it.value('DB.name'),it.value('DB.owner')])}); t.unique(); }"; - String exMain = "g.V().has('__typeName', 'DB').as('d').order().by('DB.owner').limit(25).toList()"; + String exMain = "g.V().has('__typeName', 'DB').as('d').order().by('DB.owner').limit(local, 25).limit(25).toList()"; verify("DB as d select d.name, d.owner orderby (d.owner) limit 25", getExpected(exSel, exMain)); - String exMain2 = "g.V().has('__typeName', 'Table').and(__.has('Table.name', eq(\"sales_fact\")),__.has('Table.createTime', gt('1418265300000'))).order().by('Table.createTime').limit(25).toList()"; + String exMain2 = "g.V().has('__typeName', 'Table').and(__.has('Table.name', eq(\"sales_fact\")),__.has('Table.createTime', gt('1418265300000'))).order().by('Table.createTime').limit(local, 25).limit(25).toList()"; String exSel2 = "def f(r){ t=[['_col_0','_col_1']]; r.each({t.add([it.value('Table.name'),it.value('Table.createTime')])}); t.unique(); }"; verify("Table where (name = \"sales_fact\" and createTime > \"2014-12-11T02:35:0.0Z\" ) select name as _col_0, createTime as _col_1 orderby _col_1", getExpected(exSel2, exMain2)); @@ -143,49 +140,49 @@ public class GremlinQueryComposerTest { @Test public void fromDBOrderByNameDesc() { - verify("from DB orderby name DESC", "g.V().has('__typeName', 'DB').order().by('DB.name', decr).limit(25).toList()"); + verify("from DB orderby name DESC", "g.V().has('__typeName', 'DB').order().by('DB.name', decr).limit(local, 25).limit(25).toList()"); } @Test public void fromDBSelect() { - String expected = "def f(r){ t=[['DB.name','DB.owner']]; r.each({t.add([it.value('DB.name'),it.value('DB.owner')])}); t.unique(); }; f(g.V().has('__typeName', 'DB').limit(25).toList())"; + String expected = "def f(r){ t=[['DB.name','DB.owner']]; r.each({t.add([it.value('DB.name'),it.value('DB.owner')])}); t.unique(); }; f(g.V().has('__typeName', 'DB').limit(local, 25).limit(25).toList())"; verify("from DB select DB.name, DB.owner", expected); } @Test public void fromDBGroupBy() { - verify("from DB groupby (DB.owner)", "g.V().has('__typeName', 'DB').group().by('DB.owner').limit(25).toList()"); + verify("from DB groupby (DB.owner)", "g.V().has('__typeName', 'DB').group().by('DB.owner').limit(local, 25).limit(25).toList()"); } @Test public void whereClauseTextContains() { - String exMain = "g.V().has('__typeName', 'DB').has('DB.name', eq(\"Reporting\")).limit(25).toList()"; + String exMain = "g.V().has('__typeName', 'DB').has('DB.name', eq(\"Reporting\")).limit(local, 25).limit(25).toList()"; String exSel = "def f(r){ t=[['name','owner']]; r.each({t.add([it.value('DB.name'),it.value('DB.owner')])}); t.unique(); }"; verify("from DB where name = \"Reporting\" select name, owner", getExpected(exSel, exMain)); verify("from DB where (name = \"Reporting\") select name, owner", getExpected(exSel, exMain)); verify("Table where Asset.name like \"Tab*\"", - "g.V().has('__typeName', 'Table').has('Table.name', org.janusgraph.core.attribute.Text.textRegex(\"Tab.*\")).limit(25).toList()"); + "g.V().has('__typeName', 'Table').has('Table.name', org.janusgraph.core.attribute.Text.textRegex(\"Tab.*\")).limit(local, 25).limit(25).toList()"); verify("from Table where (db.name = \"Reporting\")", - "g.V().has('__typeName', 'Table').out('__Table.db').has('DB.name', eq(\"Reporting\")).dedup().in('__Table.db').limit(25).toList()"); + "g.V().has('__typeName', 'Table').out('__Table.db').has('DB.name', eq(\"Reporting\")).dedup().in('__Table.db').limit(local, 25).limit(25).toList()"); } @Test public void whereClauseWithAsTextContains() { String exSel = "def f(r){ t=[['t.name','t.owner']]; r.each({t.add([it.value('Table.name'),it.value('Table.owner')])}); t.unique(); }"; - String exMain = "g.V().has('__typeName', 'Table').as('t').has('Table.name', eq(\"testtable_1\")).limit(25).toList()"; + String exMain = "g.V().has('__typeName', 'Table').as('t').has('Table.name', eq(\"testtable_1\")).limit(local, 25).limit(25).toList()"; verify("Table as t where t.name = \"testtable_1\" select t.name, t.owner", getExpected(exSel, exMain)); } @Test public void whereClauseWithDateCompare() { String exSel = "def f(r){ t=[['t.name','t.owner']]; r.each({t.add([it.value('Table.name'),it.value('Table.owner')])}); t.unique(); }"; - String exMain = "g.V().has('__typeName', 'Table').as('t').has('Table.createTime', eq('1513046158440')).limit(25).toList()"; + String exMain = "g.V().has('__typeName', 'Table').as('t').has('Table.createTime', eq('1513046158440')).limit(local, 25).limit(25).toList()"; verify("Table as t where t.createTime = \"2017-12-12T02:35:58.440Z\" select t.name, t.owner", getExpected(exSel, exMain)); } @Test public void subType() { - String exMain = "g.V().has('__typeName', within('Asset','Table')).limit(25).toList()"; + String exMain = "g.V().has('__typeName', within('Asset','Table')).limit(local, 25).limit(25).toList()"; String exSel = "def f(r){ t=[['name','owner']]; r.each({t.add([it.value('Asset.name'),it.value('Asset.owner')])}); t.unique(); }"; verify("Asset select name, owner", getExpected(exSel, exMain)); @@ -194,24 +191,24 @@ public class GremlinQueryComposerTest { @Test public void countMinMax() { verify("from DB groupby (owner) select count()", - "def f(l){ t=[['count()']]; l.get(0).each({k,r -> L:{ def count=r.size(); t.add([count]); } }); t; }; f(g.V().has('__typeName', 'DB').group().by('DB.owner').limit(25).toList())"); + "def f(l){ t=[['count()']]; l.get(0).each({k,r -> L:{ def count=r.size(); t.add([count]); } }); t; }; f(g.V().has('__typeName', 'DB').group().by('DB.owner').limit(local, 25).limit(25).toList())"); verify("from DB groupby (owner) select max(name)", - "def f(l){ t=[['max(name)']]; l.get(0).each({k,r -> L:{ def max=r.max({it.value('DB.name')}).value('DB.name'); t.add([max]); } }); t; }; f(g.V().has('__typeName', 'DB').group().by('DB.owner').limit(25).toList())"); + "def f(l){ t=[['max(name)']]; l.get(0).each({k,r -> L:{ def max=r.max({it.value('DB.name')}).value('DB.name'); t.add([max]); } }); t; }; f(g.V().has('__typeName', 'DB').group().by('DB.owner').limit(local, 25).limit(25).toList())"); verify("from DB groupby (owner) select min(name)", - "def f(l){ t=[['min(name)']]; l.get(0).each({k,r -> L:{ def min=r.min({it.value('DB.name')}).value('DB.name'); t.add([min]); } }); t; }; f(g.V().has('__typeName', 'DB').group().by('DB.owner').limit(25).toList())"); + "def f(l){ t=[['min(name)']]; l.get(0).each({k,r -> L:{ def min=r.min({it.value('DB.name')}).value('DB.name'); t.add([min]); } }); t; }; f(g.V().has('__typeName', 'DB').group().by('DB.owner').limit(local, 25).limit(25).toList())"); verify("from Table select sum(createTime)", - "def f(r){ t=[['sum(createTime)']]; def sum=r.sum({it.value('Table.createTime')}); t.add([sum]); t;}; f(g.V().has('__typeName', 'Table').limit(25).toList())"); + "def f(r){ t=[['sum(createTime)']]; def sum=r.sum({it.value('Table.createTime')}); t.add([sum]); t;}; f(g.V().has('__typeName', 'Table').limit(local, 25).limit(25).toList())"); } @Test public void traitWithSpace() { - verify("`Log Data`", "g.V().has('__typeName', 'Log Data').limit(25).toList()"); + verify("`Log Data`", "g.V().has('__typeName', 'Log Data').limit(local, 25).limit(25).toList()"); } @Test public void whereClauseWithBooleanCondition() { String queryFormat = "Table as t where name ='Reporting' or t.isFile = %s"; - String expectedFormat = "g.V().has('__typeName', 'Table').as('t').or(__.has('Table.name', eq('Reporting')),__.has('Table.isFile', eq(%s))).limit(25).toList()"; + String expectedFormat = "g.V().has('__typeName', 'Table').as('t').or(__.has('Table.name', eq('Reporting')),__.has('Table.isFile', eq(%s))).limit(local, 25).limit(25).toList()"; verify(String.format(queryFormat, "true"), String.format(expectedFormat, "true")); verify(String.format(queryFormat, "false"), String.format(expectedFormat, "false")); verify(String.format(queryFormat, "True"), String.format(expectedFormat, "True")); @@ -222,23 +219,23 @@ public class GremlinQueryComposerTest { private Object[][] nestedQueriesSource() { return new Object[][]{ {"Table where name=\"sales_fact\" or name=\"testtable_1\"", - "g.V().has('__typeName', 'Table').or(__.has('Table.name', eq(\"sales_fact\")),__.has('Table.name', eq(\"testtable_1\"))).limit(25).toList()"}, + "g.V().has('__typeName', 'Table').or(__.has('Table.name', eq(\"sales_fact\")),__.has('Table.name', eq(\"testtable_1\"))).limit(local, 25).limit(25).toList()"}, {"Table where name=\"sales_fact\" and name=\"testtable_1\"", - "g.V().has('__typeName', 'Table').and(__.has('Table.name', eq(\"sales_fact\")),__.has('Table.name', eq(\"testtable_1\"))).limit(25).toList()"}, + "g.V().has('__typeName', 'Table').and(__.has('Table.name', eq(\"sales_fact\")),__.has('Table.name', eq(\"testtable_1\"))).limit(local, 25).limit(25).toList()"}, {"Table where name=\"sales_fact\" or name=\"testtable_1\" or name=\"testtable_2\"", "g.V().has('__typeName', 'Table')" + ".or(" + "__.has('Table.name', eq(\"sales_fact\"))," + "__.has('Table.name', eq(\"testtable_1\"))," + "__.has('Table.name', eq(\"testtable_2\"))" + - ").limit(25).toList()"}, + ").limit(local, 25).limit(25).toList()"}, {"Table where name=\"sales_fact\" and name=\"testtable_1\" and name=\"testtable_2\"", "g.V().has('__typeName', 'Table')" + ".and(" + "__.has('Table.name', eq(\"sales_fact\"))," + "__.has('Table.name', eq(\"testtable_1\"))," + "__.has('Table.name', eq(\"testtable_2\"))" + - ").limit(25).toList()"}, + ").limit(local, 25).limit(25).toList()"}, {"Table where (name=\"sales_fact\" or name=\"testtable_1\") and name=\"testtable_2\"", "g.V().has('__typeName', 'Table')" + ".and(" + @@ -247,7 +244,7 @@ public class GremlinQueryComposerTest { "__.has('Table.name', eq(\"testtable_1\"))" + ")," + "__.has('Table.name', eq(\"testtable_2\")))" + - ".limit(25).toList()"}, + ".limit(local, 25).limit(25).toList()"}, {"Table where name=\"sales_fact\" or (name=\"testtable_1\" and name=\"testtable_2\")", "g.V().has('__typeName', 'Table')" + ".or(" + @@ -256,7 +253,7 @@ public class GremlinQueryComposerTest { "__.has('Table.name', eq(\"testtable_1\"))," + "__.has('Table.name', eq(\"testtable_2\")))" + ")" + - ".limit(25).toList()"}, + ".limit(local, 25).limit(25).toList()"}, {"Table where name=\"sales_fact\" or name=\"testtable_1\" and name=\"testtable_2\"", "g.V().has('__typeName', 'Table')" + ".and(" + @@ -265,7 +262,7 @@ public class GremlinQueryComposerTest { "__.has('Table.name', eq(\"testtable_1\"))" + ")," + "__.has('Table.name', eq(\"testtable_2\")))" + - ".limit(25).toList()"}, + ".limit(local, 25).limit(25).toList()"}, {"Table where (name=\"sales_fact\" and owner=\"Joe\") OR (name=\"sales_fact_daily_mv\" and owner=\"Joe BI\")", "g.V().has('__typeName', 'Table')" + ".or(" + @@ -277,13 +274,13 @@ public class GremlinQueryComposerTest { "__.has('Table.name', eq(\"sales_fact_daily_mv\"))," + "__.has('Table.owner', eq(\"Joe BI\"))" + "))" + - ".limit(25).toList()"}, + ".limit(local, 25).limit(25).toList()"}, {"Table where owner=\"hdfs\" or ((name=\"testtable_1\" or name=\"testtable_2\") and createTime < \"2017-12-12T02:35:58.440Z\")", - "g.V().has('__typeName', 'Table').or(__.has('Table.owner', eq(\"hdfs\")),__.and(__.or(__.has('Table.name', eq(\"testtable_1\")),__.has('Table.name', eq(\"testtable_2\"))),__.has('Table.createTime', lt('1513046158440')))).limit(25).toList()"}, + "g.V().has('__typeName', 'Table').or(__.has('Table.owner', eq(\"hdfs\")),__.and(__.or(__.has('Table.name', eq(\"testtable_1\")),__.has('Table.name', eq(\"testtable_2\"))),__.has('Table.createTime', lt('1513046158440')))).limit(local, 25).limit(25).toList()"}, {"hive_db where hive_db.name='Reporting' and hive_db.createTime < '2017-12-12T02:35:58.440Z'", - "g.V().has('__typeName', 'hive_db').and(__.has('hive_db.name', eq('Reporting')),__.has('hive_db.createTime', lt('1513046158440'))).limit(25).toList()"}, + "g.V().has('__typeName', 'hive_db').and(__.has('hive_db.name', eq('Reporting')),__.has('hive_db.createTime', lt('1513046158440'))).limit(local, 25).limit(25).toList()"}, {"Table where db.name='Sales' and db.clusterName='cl1'", - "g.V().has('__typeName', 'Table').and(__.out('__Table.db').has('DB.name', eq('Sales')).dedup().in('__Table.db'),__.out('__Table.db').has('DB.clusterName', eq('cl1')).dedup().in('__Table.db')).limit(25).toList()"}, + "g.V().has('__typeName', 'Table').and(__.out('__Table.db').has('DB.name', eq('Sales')).dedup().in('__Table.db'),__.out('__Table.db').has('DB.clusterName', eq('cl1')).dedup().in('__Table.db')).limit(local, 25).limit(25).toList()"}, }; } @@ -296,25 +293,57 @@ public class GremlinQueryComposerTest { @Test public void keywordsInWhereClause() { verify("Table as t where t has name and t isa Dimension", - "g.V().has('__typeName', 'Table').as('t').and(__.has('Table.name'),__.has('__traitNames', within('Dimension'))).limit(25).toList()"); - + "g.V().has('__typeName', 'Table').as('t').and(__.has('Table.name'),__.has('__traitNames', within('Dimension'))).limit(local, 25).limit(25).toList()"); verify("Table as t where t has name and t.name = 'sales_fact'", - "g.V().has('__typeName', 'Table').as('t').and(__.has('Table.name'),__.has('Table.name', eq('sales_fact'))).limit(25).toList()"); + "g.V().has('__typeName', 'Table').as('t').and(__.has('Table.name'),__.has('Table.name', eq('sales_fact'))).limit(local, 25).limit(25).toList()"); verify("Table as t where t is Dimension and t.name = 'sales_fact'", - "g.V().has('__typeName', 'Table').as('t').and(__.has('__traitNames', within('Dimension')),__.has('Table.name', eq('sales_fact'))).limit(25).toList()"); - verify("Table isa 'Dimension' and t.name = 'sales_fact'", "g.V().has('__typeName', 'Table').has('__traitNames', within(''Dimension'')).limit(25).toList()"); + "g.V().has('__typeName', 'Table').as('t').and(__.has('__traitNames', within('Dimension')),__.has('Table.name', eq('sales_fact'))).limit(local, 25).limit(25).toList()"); + verify("Table isa 'Dimension' and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.has('__traitNames', within('Dimension')),__.has('Table.name', eq('sales_fact'))).limit(local, 25).limit(25).toList()"); + verify("Table has name and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.has('Table.name'),__.has('Table.name', eq('sales_fact'))).limit(local, 25).limit(25).toList()"); + verify("Table is 'Dimension' and Table has owner and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.has('__traitNames', within('Dimension')),__.has('Table.owner'),__.has('Table.name', eq('sales_fact'))).limit(local, 25).limit(25).toList()"); + verify("Table has name and Table has owner and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.has('Table.name'),__.has('Table.owner'),__.has('Table.name', eq('sales_fact'))).limit(local, 25).limit(25).toList()"); + } + + @Test + public void systemAttributes() { + verify("Table has __state", "g.V().has('__typeName', 'Table').has('__state').limit(local, 25).limit(25).toList()"); + verify("Table select __guid", "def f(r){ t=[['__guid']]; r.each({t.add([it.value('__guid')])}); t.unique(); }; f(g.V().has('__typeName', 'Table').limit(local, 25).limit(25).toList())"); + verify("Table as t where t.__state = 'ACTIVE'", "g.V().has('__typeName', 'Table').as('t').has('__state', eq('ACTIVE')).limit(local, 25).limit(25).toList()"); } @Test public void invalidQueries() { verify("hdfs_path like h1", ""); -// verify("hdfs_path select xxx", ""); } - private void verify(String dsl, String expectedGremlin) { + @Test + public void invalidQueries2() { + verify("PIII", 3); + verify("TableTTT where name = 'abcd'", 1); + verify("Table isa Table", 1); + verify("Table has xxx", 1); + verify("Table where createType = '2010-03-30'", 1); + verify("Table has db", 1); + verify("Table groupby(db) select name", 1); + verify("Table groupby(name) select name, max(db)", 1); + verify("Table select db, columns", 2); + verify("Table select db, owner, columns", 3); + } + + private void verify(String dsl, String expectedGremlin, int expectedNumberOfErrors) { AtlasDSLParser.QueryContext queryContext = getParsedQuery(dsl); - String actualGremlin = getGremlinQuery(queryContext); - assertEquals(actualGremlin, expectedGremlin); + String actualGremlin = getGremlinQuery(dsl, queryContext, expectedNumberOfErrors); + if(expectedNumberOfErrors == 0) { + assertEquals(actualGremlin, expectedGremlin, dsl); + } + } + + private void verify(String dsl, int expectedNumberOfErrors) { + verify(dsl, "", expectedNumberOfErrors); + } + + private void verify(String dsl, String expectedGremlin) { + verify(dsl, expectedGremlin, 0); } private String getExpected(String select, String main) { @@ -332,9 +361,9 @@ public class GremlinQueryComposerTest { return queryContext; } - private String getGremlinQuery(AtlasDSLParser.QueryContext queryContext) { + private String getGremlinQuery(String dsl, AtlasDSLParser.QueryContext queryContext, int expectedNumberOfErrors) { AtlasTypeRegistry registry = mock(AtlasTypeRegistry.class); - org.apache.atlas.query.Lookup lookup = new TestLookup(errorList, registry); + org.apache.atlas.query.Lookup lookup = new TestLookup(registry); GremlinQueryComposer.Context context = new GremlinQueryComposer.Context(lookup); AtlasDSL.QueryMetadata queryMetadata = new AtlasDSL.QueryMetadata(queryContext); @@ -343,35 +372,42 @@ public class GremlinQueryComposerTest { qv.visit(queryContext); String s = gremlinQueryComposer.get(); - assertEquals(gremlinQueryComposer.getErrorList().size(), 0); + int actualNumberOfErrors = gremlinQueryComposer.getErrorList().size(); + assertEquals(actualNumberOfErrors, expectedNumberOfErrors, dsl); return s; } private static class TestLookup implements org.apache.atlas.query.Lookup { - - List<String> errorList; AtlasTypeRegistry registry; - public TestLookup(List<String> errorList, AtlasTypeRegistry typeRegistry) { - this.errorList = errorList; + public TestLookup(AtlasTypeRegistry typeRegistry) { this.registry = typeRegistry; } @Override - public AtlasType getType(String typeName) { - AtlasType type = null; + public AtlasType getType(String typeName) throws AtlasBaseException { + AtlasType type; if(typeName.equals("PII") || typeName.equals("Dimension")) { type = mock(AtlasType.class); + when(type.getTypeCategory()).thenReturn(TypeCategory.CLASSIFICATION); } else { type = mock(AtlasEntityType.class); + when(type.getTypeCategory()).thenReturn(TypeCategory.ENTITY); } + if(typeName.equals("PIII")) { + throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND); + } when(type.getTypeName()).thenReturn(typeName); return type; } @Override public String getQualifiedName(GremlinQueryComposer.Context context, String name) throws AtlasBaseException { + if(name.startsWith("__")) { + return name.equals("__state") || name.equals("__guid") ? name : ""; + } + if(!hasAttribute(context, name)) { throw new AtlasBaseException("Invalid attribute"); } @@ -390,7 +426,9 @@ public class GremlinQueryComposerTest { return attributeName.equals("name") || attributeName.equals("owner") || attributeName.equals("createTime") || - attributeName.equals("clusterName"); + attributeName.equals("clusterName") || + attributeName.equals("__guid") || + attributeName.equals("__state"); } @Override @@ -412,6 +450,8 @@ public class GremlinQueryComposerTest { (context.getActiveTypeName().equals("Table") && attributeName.equals("owner")) || (context.getActiveTypeName().equals("Table") && attributeName.equals("clusterName")) || (context.getActiveTypeName().equals("Table") && attributeName.equals("isFile")) || + (context.getActiveTypeName().equals("Table") && attributeName.equals("__guid")) || + (context.getActiveTypeName().equals("Table") && attributeName.equals("__state")) || (context.getActiveTypeName().equals("hive_db") && attributeName.equals("name")) || (context.getActiveTypeName().equals("hive_db") && attributeName.equals("owner")) || (context.getActiveTypeName().equals("hive_db") && attributeName.equals("createTime")) || @@ -434,8 +474,8 @@ public class GremlinQueryComposerTest { } @Override - public boolean isTraitType(GremlinQueryComposer.Context context) { - return context.getActiveTypeName().equals("PII") || context.getActiveTypeName().equals("Dimension"); + public boolean isTraitType(String typeName) { + return typeName.equals("PII") || typeName.equals("Dimension"); } @Override
