Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
atlas
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dataplatform
atlas
Commits
af99895b
Commit
af99895b
authored
Mar 27, 2015
by
Harish Butani
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
flush out Hive lineage query implementations
parent
fb3f6b46
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
110 additions
and
19 deletions
+110
-19
ClosureQuery.scala
...scala/org/apache/hadoop/metadata/query/ClosureQuery.scala
+84
-12
QueryProcessor.scala
...ala/org/apache/hadoop/metadata/query/QueryProcessor.scala
+7
-7
GremlinTest2.scala
...scala/org/apache/hadoop/metadata/query/GremlinTest2.scala
+19
-0
No files found.
repository/src/main/scala/org/apache/hadoop/metadata/query/ClosureQuery.scala
View file @
af99895b
...
...
@@ -18,7 +18,10 @@
package
org.apache.hadoop.metadata.query
import
Expressions._
import
com.thinkaurelius.titan.core.TitanGraph
import
org.apache.hadoop.metadata.typesystem.types.DataTypes
import
org.apache.hadoop.metadata.typesystem.types.DataTypes.PrimitiveType
/**
* Represents a Query to compute the closure based on a relationship between entities of a particular type.
...
...
@@ -59,9 +62,20 @@ import com.thinkaurelius.titan.core.TitanGraph
*/
trait
ClosureQuery
{
sealed
trait
PathAttribute
case
class
ReverseRelation
(
typeName
:
String
,
attributeName
:
String
)
case
class
Relation
(
attributeName
:
String
)
sealed
trait
PathAttribute
{
def
toExpr
:
Expression
=
this
match
{
case
r
:
Relation
=>
id
(
r
.
attributeName
)
case
rr
:
ReverseRelation
=>
id
(
rr
.
typeName
)
}
def
toFieldName
:
String
=
this
match
{
case
r
:
Relation
=>
r
.
attributeName
case
rr
:
ReverseRelation
=>
rr
.
typeName
}
}
case
class
ReverseRelation
(
typeName
:
String
,
attributeName
:
String
)
extends
PathAttribute
case
class
Relation
(
attributeName
:
String
)
extends
PathAttribute
/**
* Type on whose instances the closure needs to be computed
...
...
@@ -71,9 +85,8 @@ trait ClosureQuery {
/**
* specify how instances are related.
* @param attributePath
*/
def
closureRelation
(
attributePath
:
List
[
PathAttribute
])
def
closureRelation
:
List
[
PathAttribute
]
/**
* The maximum hops between related instances. A [[None]] implies there is maximum.
...
...
@@ -97,7 +110,54 @@ trait ClosureQuery {
def
persistenceStrategy
:
GraphPersistenceStrategies
def
g
:
TitanGraph
def
evaluate
()
:
GremlinQueryResult
=
???
def
pathExpr
:
Expressions.Expression
=
{
closureRelation
.
tail
.
foldLeft
(
closureRelation
.
head
.
toExpr
)((
b
,
a
)
=>
b
.
field
(
a
.
toFieldName
))
}
def
selectExpr
(
alias
:
String
)
:
List
[
Expression
]
=
{
selectAttributes
.
map
{
_
.
map
{
a
=>
id
(
alias
).
field
(
a
).
as
(
s
"${alias}_$a"
)
}
}.
getOrElse
(
List
(
id
(
alias
)))
}
/**
* hook to allow a filter to be added for the closureType
* @param expr
* @return
*/
def
srcCondition
(
expr
:
Expression
)
:
Expression
=
expr
def
expr
:
Expressions.Expression
=
{
val
e
=
srcCondition
(
Expressions
.
_class
(
closureType
)).
as
(
"src"
).
loop
(
pathExpr
).
as
(
"dest"
).
select
((
selectExpr
(
"src"
)
++
selectExpr
(
"dest"
))
:_
*
)
if
(
withPath
)
e
.
path
else
e
}
def
evaluate
()
:
GremlinQueryResult
=
{
var
e
=
expr
QueryProcessor
.
evaluate
(
e
,
g
,
persistenceStrategy
)
}
}
/**
* Closure for a single instance. Instance is specified by an ''attributeToSelectInstance'' and the value
* for the attribute.
*
* @tparam T
*/
trait
SingleInstanceClosureQuery
[
T
]
extends
ClosureQuery
{
def
attributeToSelectInstance
:
String
def
attributeTyp
:
PrimitiveType
[
T
]
def
instanceValue
:
T
override
def
srcCondition
(
expr
:
Expression
)
:
Expression
=
{
expr
.
where
(
Expressions
.
id
(
attributeToSelectInstance
).
`=`
(
Expressions
.
literal
(
attributeTyp
,
instanceValue
))
)
}
}
/**
...
...
@@ -115,6 +175,7 @@ trait ClosureQuery {
* @param g as needed to evaluate the Closure Query.
*/
case
class
HiveLineageQuery
(
tableTypeName
:
String
,
tableName
:
String
,
ctasTypeName
:
String
,
ctasInputTableAttribute
:
String
,
ctasOutputTableAttribute
:
String
,
...
...
@@ -123,11 +184,16 @@ case class HiveLineageQuery(tableTypeName : String,
withPath
:
Boolean
,
persistenceStrategy
:
GraphPersistenceStrategies
,
g
:
TitanGraph
)
extends
ClosureQuery
{
)
extends
SingleInstanceClosureQuery
[
String
]
{
val
closureType
:
String
=
tableTypeName
val
attributeToSelectInstance
=
"name"
val
attributeTyp
=
DataTypes
.
STRING_TYPE
def
closureType
:
String
=
tableTyp
eName
val
instanceValue
=
tabl
eName
def
closureRelation
(
attributePath
:
List
[
PathAttribute
])
=
List
(
lazy
val
closureRelation
=
List
(
ReverseRelation
(
ctasTypeName
,
ctasOutputTableAttribute
),
Relation
(
ctasInputTableAttribute
)
)
...
...
@@ -149,6 +215,7 @@ case class HiveLineageQuery(tableTypeName : String,
* @param g as needed to evaluate the Closure Query.
*/
case
class
HiveWhereUsedQuery
(
tableTypeName
:
String
,
tableName
:
String
,
ctasTypeName
:
String
,
ctasInputTableAttribute
:
String
,
ctasOutputTableAttribute
:
String
,
...
...
@@ -157,11 +224,16 @@ case class HiveWhereUsedQuery(tableTypeName : String,
withPath
:
Boolean
,
persistenceStrategy
:
GraphPersistenceStrategies
,
g
:
TitanGraph
)
extends
ClosureQuery
{
)
extends
SingleInstanceClosureQuery
[
String
]
{
val
closureType
:
String
=
tableTypeName
val
attributeToSelectInstance
=
"name"
val
attributeTyp
=
DataTypes
.
STRING_TYPE
def
closureType
:
String
=
tableTyp
eName
val
instanceValue
=
tabl
eName
def
closureRelation
(
attributePath
:
List
[
PathAttribute
])
=
List
(
lazy
val
closureRelation
=
List
(
ReverseRelation
(
ctasTypeName
,
ctasInputTableAttribute
),
Relation
(
ctasOutputTableAttribute
)
)
...
...
repository/src/main/scala/org/apache/hadoop/metadata/query/QueryProcessor.scala
View file @
af99895b
...
...
@@ -23,15 +23,15 @@ import org.apache.hadoop.metadata.query.Expressions._
object
QueryProcessor
{
def
evaluate
(
e
:
Expression
,
g
:
TitanGraph
)
:
GremlinQueryResult
=
{
val
gP
=
GraphPersistenceStrategy1
def
evaluate
(
e
:
Expression
,
g
:
TitanGraph
,
gP
:
GraphPersistenceStrategies
=
GraphPersistenceStrategy1
)
:
GremlinQueryResult
=
{
val
e1
=
validate
(
e
)
val
q
=
new
GremlinTranslator
(
e1
,
gP
).
translate
()
//
println("---------------------")
//
println("Query: " + e1)
//
println("Expression Tree:\n" + e1.treeString)
//
println("Gremlin Query: " + q.queryStr)
//
println("---------------------")
//
println("---------------------")
//
println("Query: " + e1)
//
println("Expression Tree:\n" + e1.treeString)
//
println("Gremlin Query: " + q.queryStr)
//
println("---------------------")
new
GremlinEvaluator
(
q
,
gP
,
g
).
evaluate
()
}
...
...
repository/src/test/scala/org/apache/hadoop/metadata/query/GremlinTest2.scala
View file @
af99895b
...
...
@@ -86,4 +86,22 @@ class GremlinTest2 extends FunSuite with BeforeAndAfterAll with BaseGremlinTest
validateJson
(
r
)
}
// test("testLineageAllSelectWithPathFromParser2") {
// val p = new QueryParser
// val e = p("Table as src loop (LoadProcess inputTables) as dest " +
// "select src.name as srcTable, dest.name as destTable withPath").right.get
// //Table as src loop (LoadProcess where LoadProcess.outputTable) as dest select src.name as srcTable, dest.name as destTable withPath
// val r = QueryProcessor.evaluate(e, g)
// validateJson(r)
// }
//
// test("testHighLevelLineage") {
// val r = HiveLineageQuery("Table", "sales_daily_mv",
// "LoadProcess",
// "inputTables",
// "outputTable",
// None, Some(List("name")), true, GraphPersistenceStrategy1, g).evaluate()
// validateJson(r)
// }
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment