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
69af0ae7
Commit
69af0ae7
authored
8 years ago
by
Jeff Hagelberg
Committed by
Dave Kantor
8 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ATLAS-1195 Clean up DSL Translation (jnhagelb via dkantor)
parent
aa15cd0a
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
2341 additions
and
475 deletions
+2341
-475
AbstractGroovyExpression.java
...ava/org/apache/atlas/groovy/AbstractGroovyExpression.java
+36
-0
ArithmeticExpression.java
...in/java/org/apache/atlas/groovy/ArithmeticExpression.java
+59
-0
BinaryExpression.java
...c/main/java/org/apache/atlas/groovy/BinaryExpression.java
+51
-0
CastExpression.java
...src/main/java/org/apache/atlas/groovy/CastExpression.java
+44
-0
ClosureExpression.java
.../main/java/org/apache/atlas/groovy/ClosureExpression.java
+63
-0
CodeBlockExpression.java
...ain/java/org/apache/atlas/groovy/CodeBlockExpression.java
+61
-0
ComparisonExpression.java
...in/java/org/apache/atlas/groovy/ComparisonExpression.java
+64
-0
ComparisonOperatorExpression.java
...org/apache/atlas/groovy/ComparisonOperatorExpression.java
+32
-0
FieldExpression.java
...rc/main/java/org/apache/atlas/groovy/FieldExpression.java
+44
-0
FunctionCallExpression.java
.../java/org/apache/atlas/groovy/FunctionCallExpression.java
+86
-0
GroovyExpression.java
...c/main/java/org/apache/atlas/groovy/GroovyExpression.java
+34
-0
GroovyGenerationContext.java
...java/org/apache/atlas/groovy/GroovyGenerationContext.java
+68
-0
IdentifierExpression.java
...in/java/org/apache/atlas/groovy/IdentifierExpression.java
+42
-0
ListExpression.java
...src/main/java/org/apache/atlas/groovy/ListExpression.java
+60
-0
LiteralExpression.java
.../main/java/org/apache/atlas/groovy/LiteralExpression.java
+99
-0
LogicalExpression.java
.../main/java/org/apache/atlas/groovy/LogicalExpression.java
+46
-0
RangeExpression.java
...rc/main/java/org/apache/atlas/groovy/RangeExpression.java
+45
-0
TernaryOperatorExpression.java
...va/org/apache/atlas/groovy/TernaryOperatorExpression.java
+56
-0
TypeCoersionExpression.java
.../java/org/apache/atlas/groovy/TypeCoersionExpression.java
+44
-0
VariableAssignmentExpression.java
...org/apache/atlas/groovy/VariableAssignmentExpression.java
+58
-0
AtlasGraph.java
.../java/org/apache/atlas/repository/graphdb/AtlasGraph.java
+4
-3
Titan0Graph.java
...g/apache/atlas/repository/graphdb/titan0/Titan0Graph.java
+6
-5
release-log.txt
release-log.txt
+1
-0
DefaultGraphPersistenceStrategy.java
...tlas/discovery/graph/DefaultGraphPersistenceStrategy.java
+11
-36
Gremlin2ExpressionFactory.java
...a/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
+223
-0
Gremlin3ExpressionFactory.java
...a/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
+325
-0
GremlinExpressionFactory.java
...va/org/apache/atlas/gremlin/GremlinExpressionFactory.java
+410
-0
GraphPersistenceStrategies.scala
...a/org/apache/atlas/query/GraphPersistenceStrategies.scala
+23
-152
GremlinQuery.scala
.../src/main/scala/org/apache/atlas/query/GremlinQuery.scala
+246
-279
No files found.
common/src/main/java/org/apache/atlas/groovy/AbstractGroovyExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Abstract implementation of GroovyExpression that adds a convenient
* toString method.
*
*/
public
abstract
class
AbstractGroovyExpression
implements
GroovyExpression
{
@Override
public
String
toString
()
{
GroovyGenerationContext
ctx
=
new
GroovyGenerationContext
();
ctx
.
setParametersAllowed
(
false
);
generateGroovy
(
ctx
);
return
ctx
.
getQuery
();
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
import
org.apache.atlas.AtlasException
;
/**
* Represents an arithmetic expression such as a+b.
*/
public
class
ArithmeticExpression
extends
BinaryExpression
{
/**
* Allowed arithmetic operators.
*/
public
enum
ArithmeticOperator
{
PLUS
(
"+"
),
MINUS
(
"-"
),
TIMES
(
"*"
),
DIVIDE
(
"/"
),
MODULUS
(
"%"
);
private
String
groovyValue
;
ArithmeticOperator
(
String
groovyValue
)
{
this
.
groovyValue
=
groovyValue
;
}
public
String
getGroovyValue
()
{
return
groovyValue
;
}
public
static
ArithmeticOperator
lookup
(
String
groovyValue
)
throws
AtlasException
{
for
(
ArithmeticOperator
op
:
ArithmeticOperator
.
values
())
{
if
(
op
.
getGroovyValue
().
equals
(
groovyValue
))
{
return
op
;
}
}
throw
new
AtlasException
(
"Unknown Operator:"
+
groovyValue
);
}
}
public
ArithmeticExpression
(
GroovyExpression
left
,
ArithmeticOperator
op
,
GroovyExpression
right
)
{
super
(
left
,
op
.
getGroovyValue
(),
right
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/BinaryExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Represents any kind of binary expression. This could
* be an arithmetic expression, such as a + 3, a boolean
* expression such as a < 5, or even a comparison function
* such as a <=> b.
*
*/
public
abstract
class
BinaryExpression
extends
AbstractGroovyExpression
{
private
GroovyExpression
left
;
private
GroovyExpression
right
;
private
String
op
;
public
BinaryExpression
(
GroovyExpression
left
,
String
op
,
GroovyExpression
right
)
{
this
.
left
=
left
;
this
.
op
=
op
;
this
.
right
=
right
;
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
left
.
generateGroovy
(
context
);
context
.
append
(
" "
);
context
.
append
(
op
);
context
.
append
(
" "
);
right
.
generateGroovy
(
context
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/CastExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Groovy expression that represents a cast.
*/
public
class
CastExpression
extends
AbstractGroovyExpression
{
private
GroovyExpression
expr
;
private
String
className
;
public
CastExpression
(
GroovyExpression
expr
,
String
className
)
{
this
.
expr
=
expr
;
this
.
className
=
className
;
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
context
.
append
(
"(("
);
context
.
append
(
className
);
context
.
append
(
")"
);
expr
.
generateGroovy
(
context
);
context
.
append
(
")"
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/ClosureExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.List
;
/**
* Groovy expression that represents a Groovy closure.
*/
public
class
ClosureExpression
extends
AbstractGroovyExpression
{
private
List
<
String
>
varNames
=
new
ArrayList
<>();
private
GroovyExpression
body
;
public
ClosureExpression
(
GroovyExpression
body
,
String
...
varNames
)
{
this
.
body
=
body
;
this
.
varNames
.
addAll
(
Arrays
.
asList
(
varNames
));
}
public
ClosureExpression
(
List
<
String
>
varNames
,
GroovyExpression
body
)
{
this
.
body
=
body
;
this
.
varNames
.
addAll
(
varNames
);
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
context
.
append
(
"{"
);
if
(!
varNames
.
isEmpty
())
{
Iterator
<
String
>
varIt
=
varNames
.
iterator
();
while
(
varIt
.
hasNext
())
{
String
varName
=
varIt
.
next
();
context
.
append
(
varName
);
if
(
varIt
.
hasNext
())
{
context
.
append
(
", "
);
}
}
context
.
append
(
"->"
);
}
body
.
generateGroovy
(
context
);
context
.
append
(
"}"
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/CodeBlockExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.List
;
/**
* Groovy expression that represents a block of code
* that contains 0 or more statements that are delimited
* by semicolons.
*/
public
class
CodeBlockExpression
extends
AbstractGroovyExpression
{
private
List
<
GroovyExpression
>
body
=
new
ArrayList
<>();
public
void
addStatement
(
GroovyExpression
expr
)
{
body
.
add
(
expr
);
}
public
void
addStatements
(
List
<
GroovyExpression
>
exprs
)
{
body
.
addAll
(
exprs
);
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
/*
* the L:{} represents a groovy code block; the label is needed
* to distinguish it from a groovy closure.
*/
context
.
append
(
"L:{"
);
Iterator
<
GroovyExpression
>
stmtIt
=
body
.
iterator
();
while
(
stmtIt
.
hasNext
())
{
GroovyExpression
stmt
=
stmtIt
.
next
();
stmt
.
generateGroovy
(
context
);
if
(
stmtIt
.
hasNext
())
{
context
.
append
(
";"
);
}
}
context
.
append
(
"}"
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/ComparisonExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
import
org.apache.atlas.AtlasException
;
/**
* Represents an expression that compares two expressions
* using a comparison operator (==, <, >, etc).
*
*/
public
class
ComparisonExpression
extends
BinaryExpression
{
/**
* Allowed comparison operators.
*
*/
public
enum
ComparisonOperator
{
GREATER_THAN_EQ_
(
">="
),
GREATER_THAN
(
">"
),
EQUALS
(
"=="
),
NOT_EQUALS
(
"!="
),
LESS_THAN
(
"<"
),
LESS_THAN_EQ
(
"<="
);
private
String
groovyValue
;
ComparisonOperator
(
String
groovyValue
)
{
this
.
groovyValue
=
groovyValue
;
}
public
String
getGroovyValue
()
{
return
groovyValue
;
}
public
static
ComparisonOperator
lookup
(
String
groovyValue
)
throws
AtlasException
{
for
(
ComparisonOperator
op
:
ComparisonOperator
.
values
())
{
if
(
op
.
getGroovyValue
().
equals
(
groovyValue
))
{
return
op
;
}
}
throw
new
AtlasException
(
"Unknown Operator:"
+
groovyValue
);
}
}
public
ComparisonExpression
(
GroovyExpression
left
,
ComparisonOperator
op
,
GroovyExpression
right
)
{
super
(
left
,
op
.
getGroovyValue
(),
right
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/ComparisonOperatorExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Represents an expression that compares two expressions using
* the Groovy "spaceship" operator. This is basically the
* same as calling left.compareTo(right), except that it has
* built-in null handling and some other nice features.
*
*/
public
class
ComparisonOperatorExpression
extends
BinaryExpression
{
public
ComparisonOperatorExpression
(
GroovyExpression
left
,
GroovyExpression
right
)
{
super
(
left
,
"<=>"
,
right
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/FieldExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Groovy expression that accesses a field in an object.
*/
public
class
FieldExpression
extends
AbstractGroovyExpression
{
private
GroovyExpression
target
;
private
String
fieldName
;
public
FieldExpression
(
GroovyExpression
target
,
String
fieldName
)
{
this
.
target
=
target
;
this
.
fieldName
=
fieldName
;
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
target
.
generateGroovy
(
context
);
context
.
append
(
".'"
);
context
.
append
(
fieldName
);
context
.
append
(
"'"
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/FunctionCallExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.List
;
/**
* Groovy expression that calls a method on an object.
*/
public
class
FunctionCallExpression
extends
AbstractGroovyExpression
{
// null for global functions
private
GroovyExpression
target
;
private
String
functionName
;
private
List
<
GroovyExpression
>
arguments
=
new
ArrayList
<
GroovyExpression
>();
public
FunctionCallExpression
(
String
functionName
,
List
<?
extends
GroovyExpression
>
arguments
)
{
this
.
target
=
null
;
this
.
functionName
=
functionName
;
this
.
arguments
.
addAll
(
arguments
);
}
public
FunctionCallExpression
(
GroovyExpression
target
,
String
functionName
,
List
<?
extends
GroovyExpression
>
arguments
)
{
this
.
target
=
target
;
this
.
functionName
=
functionName
;
this
.
arguments
.
addAll
(
arguments
);
}
public
FunctionCallExpression
(
String
functionName
,
GroovyExpression
...
arguments
)
{
this
.
target
=
null
;
this
.
functionName
=
functionName
;
this
.
arguments
.
addAll
(
Arrays
.
asList
(
arguments
));
}
public
FunctionCallExpression
(
GroovyExpression
target
,
String
functionName
,
GroovyExpression
...
arguments
)
{
this
.
target
=
target
;
this
.
functionName
=
functionName
;
this
.
arguments
.
addAll
(
Arrays
.
asList
(
arguments
));
}
public
void
addArgument
(
GroovyExpression
expr
)
{
arguments
.
add
(
expr
);
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
if
(
target
!=
null
)
{
target
.
generateGroovy
(
context
);
context
.
append
(
"."
);
}
context
.
append
(
functionName
);
context
.
append
(
"("
);
Iterator
<
GroovyExpression
>
it
=
arguments
.
iterator
();
while
(
it
.
hasNext
())
{
GroovyExpression
expr
=
it
.
next
();
expr
.
generateGroovy
(
context
);
if
(
it
.
hasNext
())
{
context
.
append
(
", "
);
}
}
context
.
append
(
")"
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/GroovyExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Represents an expression in the Groovy programming language, which
* is the language that Gremlin scripts are written and interpreted in.
*/
public
interface
GroovyExpression
{
/**
* Generates a groovy script from the expression.
*
* @param context
*/
void
generateGroovy
(
GroovyGenerationContext
context
);
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/GroovyGenerationContext.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* Context used when generating Groovy queries. Keeps track of query parameters
* that are created during the process as well as the portion of the query that
* has been generated so far.
*
*/
public
class
GroovyGenerationContext
{
private
boolean
parametersAllowed
=
true
;
private
int
parameterCount
=
0
;
private
Map
<
String
,
Object
>
parameterValues
=
new
HashMap
<>();
//used to build up the groovy script
private
StringBuilder
generatedQuery
=
new
StringBuilder
();
public
void
setParametersAllowed
(
boolean
value
)
{
this
.
parametersAllowed
=
value
;
}
public
GroovyExpression
addParameter
(
Object
value
)
{
if
(
this
.
parametersAllowed
)
{
String
parameterName
=
"p"
+
(++
parameterCount
);
this
.
parameterValues
.
put
(
parameterName
,
value
);
return
new
IdentifierExpression
(
parameterName
);
}
else
{
LiteralExpression
expr
=
new
LiteralExpression
(
value
);
expr
.
setTranslateToParameter
(
false
);
return
expr
;
}
}
public
StringBuilder
append
(
String
gremlin
)
{
this
.
generatedQuery
.
append
(
gremlin
);
return
generatedQuery
;
}
public
String
getQuery
()
{
return
generatedQuery
.
toString
();
}
public
Map
<
String
,
Object
>
getParameters
()
{
return
Collections
.
unmodifiableMap
(
parameterValues
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/IdentifierExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Groovy expression that references the variable with the given name.
*
*/
public
class
IdentifierExpression
extends
AbstractGroovyExpression
{
private
String
varName
;
public
IdentifierExpression
(
String
varName
)
{
this
.
varName
=
varName
;
}
public
String
getVariableName
()
{
return
varName
;
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
context
.
append
(
varName
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/ListExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.List
;
/**
* Groovy expression that represents a list literal.
*/
public
class
ListExpression
extends
AbstractGroovyExpression
{
private
List
<
GroovyExpression
>
values
=
new
ArrayList
<>();
public
ListExpression
(
GroovyExpression
...
values
)
{
this
.
values
=
Arrays
.
asList
(
values
);
}
public
ListExpression
(
List
<?
extends
GroovyExpression
>
values
)
{
this
.
values
.
addAll
(
values
);
}
public
void
addArgument
(
GroovyExpression
expr
)
{
values
.
add
(
expr
);
}
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
context
.
append
(
"["
);
Iterator
<
GroovyExpression
>
it
=
values
.
iterator
();
while
(
it
.
hasNext
())
{
GroovyExpression
expr
=
it
.
next
();
expr
.
generateGroovy
(
context
);
if
(
it
.
hasNext
())
{
context
.
append
(
", "
);
}
}
context
.
append
(
"]"
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/LiteralExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* Represents a literal value.
*/
public
class
LiteralExpression
implements
GroovyExpression
{
public
static
final
LiteralExpression
TRUE
=
new
LiteralExpression
(
true
);
public
static
final
LiteralExpression
FALSE
=
new
LiteralExpression
(
false
);
public
static
final
LiteralExpression
NULL
=
new
LiteralExpression
(
null
);
private
Object
value
;
private
boolean
translateToParameter
=
true
;
private
boolean
addTypeSuffix
=
false
;
public
LiteralExpression
(
Object
value
,
boolean
addTypeSuffix
)
{
this
.
value
=
value
;
this
.
translateToParameter
=
value
instanceof
String
;
this
.
addTypeSuffix
=
addTypeSuffix
;
}
public
LiteralExpression
(
Object
value
)
{
this
.
value
=
value
;
this
.
translateToParameter
=
value
instanceof
String
;
}
private
String
getTypeSuffix
()
{
if
(!
addTypeSuffix
)
{
return
""
;
}
if
(
value
.
getClass
()
==
Long
.
class
)
{
return
"L"
;
}
if
(
value
.
getClass
()
==
Float
.
class
)
{
return
"f"
;
}
if
(
value
.
getClass
()
==
Double
.
class
)
{
return
"d"
;
}
return
""
;
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
if
(
translateToParameter
)
{
GroovyExpression
result
=
context
.
addParameter
(
value
);
result
.
generateGroovy
(
context
);
return
;
}
if
(
value
instanceof
String
)
{
String
escapedValue
=
getEscapedValue
();
context
.
append
(
"'"
);
context
.
append
(
escapedValue
);
context
.
append
(
"'"
);
}
else
{
context
.
append
(
String
.
valueOf
(
value
));
context
.
append
(
getTypeSuffix
());
}
}
private
String
getEscapedValue
()
{
String
escapedValue
=
(
String
)
value
;
escapedValue
=
escapedValue
.
replaceAll
(
Pattern
.
quote
(
"\\"
),
Matcher
.
quoteReplacement
(
"\\\\"
));
escapedValue
=
escapedValue
.
replaceAll
(
Pattern
.
quote
(
"'"
),
Matcher
.
quoteReplacement
(
"\\'"
));
return
escapedValue
;
}
public
void
setTranslateToParameter
(
boolean
translateToParameter
)
{
this
.
translateToParameter
=
translateToParameter
;
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/LogicalExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Represents a logical (and/or) expression.
*
*/
public
class
LogicalExpression
extends
BinaryExpression
{
/**
* Allowed logical operators.
*
*/
public
enum
LogicalOperator
{
AND
(
"&&"
),
OR
(
"||"
);
private
String
groovyValue
;
LogicalOperator
(
String
groovyValue
)
{
this
.
groovyValue
=
groovyValue
;
}
public
String
getGroovyValue
()
{
return
groovyValue
;
}
}
public
LogicalExpression
(
GroovyExpression
left
,
LogicalOperator
op
,
GroovyExpression
right
)
{
super
(
left
,
op
.
getGroovyValue
(),
right
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/RangeExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Represents an "exclusive" range expression, e.g. [0..<10].
*/
public
class
RangeExpression
extends
AbstractGroovyExpression
{
private
GroovyExpression
parent
;
private
int
offset
;
private
int
count
;
public
RangeExpression
(
GroovyExpression
parent
,
int
offset
,
int
count
)
{
this
.
parent
=
parent
;
this
.
offset
=
offset
;
this
.
count
=
count
;
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
parent
.
generateGroovy
(
context
);
context
.
append
(
" ["
);
new
LiteralExpression
(
offset
).
generateGroovy
(
context
);
context
.
append
(
"..<"
);
new
LiteralExpression
(
count
).
generateGroovy
(
context
);
context
.
append
(
"]"
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/TernaryOperatorExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Groovy expression that represents the ternary operator (expr ? trueValue :
* falseValue)
*/
public
class
TernaryOperatorExpression
extends
AbstractGroovyExpression
{
private
GroovyExpression
booleanExpr
;
private
GroovyExpression
trueValue
;
private
GroovyExpression
falseValue
;
public
TernaryOperatorExpression
(
GroovyExpression
booleanExpr
,
GroovyExpression
trueValue
,
GroovyExpression
falseValue
)
{
this
.
booleanExpr
=
booleanExpr
;
this
.
trueValue
=
trueValue
;
this
.
falseValue
=
falseValue
;
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
context
.
append
(
"(("
);
booleanExpr
.
generateGroovy
(
context
);
context
.
append
(
") ? ("
);
trueValue
.
generateGroovy
(
context
);
context
.
append
(
") : ("
);
falseValue
.
generateGroovy
(
context
);
context
.
append
(
"))"
);
}
public
String
toString
()
{
GroovyGenerationContext
context
=
new
GroovyGenerationContext
();
generateGroovy
(
context
);
return
context
.
getQuery
();
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/TypeCoersionExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Groovy expression that represents a type coersion (e.g obj as Set).
*/
public
class
TypeCoersionExpression
extends
AbstractGroovyExpression
{
private
GroovyExpression
expr
;
private
String
className
;
public
TypeCoersionExpression
(
GroovyExpression
expr
,
String
className
)
{
this
.
expr
=
expr
;
this
.
className
=
className
;
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
context
.
append
(
"("
);
expr
.
generateGroovy
(
context
);
context
.
append
(
")"
);
context
.
append
(
" as "
);
context
.
append
(
className
);
}
}
This diff is collapsed.
Click to expand it.
common/src/main/java/org/apache/atlas/groovy/VariableAssignmentExpression.java
0 → 100644
View file @
69af0ae7
/**
* 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
.
groovy
;
/**
* Groovy statement that assigns a value to a variable.
*/
public
class
VariableAssignmentExpression
extends
AbstractGroovyExpression
{
private
String
type
=
null
;
private
String
name
;
private
GroovyExpression
value
;
/**
* @param string
* @param v
*/
public
VariableAssignmentExpression
(
String
type
,
String
name
,
GroovyExpression
v
)
{
this
.
type
=
type
;
this
.
name
=
name
;
this
.
value
=
v
;
}
public
VariableAssignmentExpression
(
String
name
,
GroovyExpression
v
)
{
this
(
null
,
name
,
v
);
}
@Override
public
void
generateGroovy
(
GroovyGenerationContext
context
)
{
if
(
type
==
null
)
{
context
.
append
(
"def "
);
}
else
{
context
.
append
(
type
);
context
.
append
(
" "
);
}
context
.
append
(
name
);
context
.
append
(
" = "
);
value
.
generateGroovy
(
context
);
}
}
This diff is collapsed.
Click to expand it.
graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraph.java
View file @
69af0ae7
...
...
@@ -23,6 +23,7 @@ import java.util.Set;
import
javax.script.ScriptException
;
import
org.apache.atlas.groovy.GroovyExpression
;
import
org.apache.atlas.typesystem.types.IDataType
;
/**
...
...
@@ -204,7 +205,7 @@ public interface AtlasGraph<V, E> {
* @param type
* @return
*/
String
generatePersisentToLogicalConversionExpression
(
String
valueExpr
,
IDataType
<?>
type
);
GroovyExpression
generatePersisentToLogicalConversionExpression
(
GroovyExpression
valueExpr
,
IDataType
<?>
type
);
/**
* Indicates whether or not stored values with the specified type need to be converted
...
...
@@ -240,7 +241,7 @@ public interface AtlasGraph<V, E> {
*
* @return
*/
String
getInitialIndexedPredicate
(
);
GroovyExpression
getInitialIndexedPredicate
(
GroovyExpression
parent
);
/**
* As an optimization, a graph database implementation may want to retrieve additional
...
...
@@ -249,7 +250,7 @@ public interface AtlasGraph<V, E> {
* avoid the need to make an extra REST API call to look up those edges. For implementations
* that do not require any kind of transform, an empty String should be returned.
*/
String
getOutputTransformationPredicate
(
boolean
isSelect
,
boolean
isPath
);
GroovyExpression
addOutputTransformationPredicate
(
GroovyExpression
expr
,
boolean
isSelect
,
boolean
isPath
);
/**
* Executes a Gremlin script, returns an object with the result.
...
...
This diff is collapsed.
Click to expand it.
graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Graph.java
View file @
69af0ae7
...
...
@@ -34,6 +34,7 @@ import javax.script.ScriptEngine;
import
javax.script.ScriptEngineManager
;
import
javax.script.ScriptException
;
import
org.apache.atlas.groovy.GroovyExpression
;
import
org.apache.atlas.repository.graphdb.AtlasEdge
;
import
org.apache.atlas.repository.graphdb.AtlasGraph
;
import
org.apache.atlas.repository.graphdb.AtlasGraphManagement
;
...
...
@@ -286,7 +287,7 @@ public class Titan0Graph implements AtlasGraph<Titan0Vertex, Titan0Edge> {
}
@Override
public
String
generatePersisentToLogicalConversionExpression
(
String
expr
,
IDataType
<?>
type
)
{
public
GroovyExpression
generatePersisentToLogicalConversionExpression
(
GroovyExpression
expr
,
IDataType
<?>
type
)
{
//nothing special needed, value is stored in required type
return
expr
;
...
...
@@ -304,13 +305,13 @@ public class Titan0Graph implements AtlasGraph<Titan0Vertex, Titan0Edge> {
}
@Override
public
String
getInitialIndexedPredicate
(
)
{
return
""
;
public
GroovyExpression
getInitialIndexedPredicate
(
GroovyExpression
expr
)
{
return
expr
;
}
@Override
public
String
getOutputTransformationPredicate
(
boolean
inSelect
,
boolean
isPath
)
{
return
""
;
public
GroovyExpression
addOutputTransformationPredicate
(
GroovyExpression
expr
,
boolean
inSelect
,
boolean
isPath
)
{
return
expr
;
}
public
Iterable
<
AtlasEdge
<
Titan0Vertex
,
Titan0Edge
>>
wrapEdges
(
Iterator
<
Edge
>
it
)
{
...
...
This diff is collapsed.
Click to expand it.
release-log.txt
View file @
69af0ae7
...
...
@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
ALL CHANGES:
ATLAS-1195 Clean up DSL Translation (jnhagelb via dkantor)
ATLAS-1139 Parameter name of a HDFS DataSet entity should contain filesystem path (svimal2106 via sumasai)
ATLAS-1200 Error Catalog enhancement (apoorvnaik via sumasai)
ATLAS-1207 Dataset exists query in lineage APIs takes longer (shwethags)
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/discovery/graph/DefaultGraphPersistenceStrategy.java
View file @
69af0ae7
...
...
@@ -23,16 +23,16 @@ import java.util.List;
import
javax.inject.Inject
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.
query.Expressions
;
import
org.apache.atlas.
groovy.GroovyExpression
;
import
org.apache.atlas.query.GraphPersistenceStrategies
;
import
org.apache.atlas.query.GraphPersistenceStrategies
$class
;
import
org.apache.atlas.query.IntSequence
;
import
org.apache.atlas.query.TypeUtils
;
import
org.apache.atlas.repository.Constants
;
import
org.apache.atlas.repository.MetadataRepository
;
import
org.apache.atlas.repository.RepositoryException
;
import
org.apache.atlas.repository.graph.GraphBackedMetadataRepository
;
import
org.apache.atlas.repository.graph.GraphHelper
;
import
org.apache.atlas.repository.graphdb.AtlasEdgeDirection
;
import
org.apache.atlas.repository.graphdb.AtlasGraph
;
import
org.apache.atlas.repository.graphdb.AtlasVertex
;
import
org.apache.atlas.repository.graphdb.GremlinVersion
;
...
...
@@ -105,11 +105,6 @@ public class DefaultGraphPersistenceStrategy implements GraphPersistenceStrategi
}
@Override
public
String
fieldPrefixInSelect
()
{
return
"it"
;
}
@Override
public
Id
getIdFromVertex
(
String
dataTypeName
,
AtlasVertex
vertex
)
{
return
GraphHelper
.
getIdFromVertex
(
dataTypeName
,
vertex
);
}
...
...
@@ -212,28 +207,13 @@ public class DefaultGraphPersistenceStrategy implements GraphPersistenceStrategi
}
@Override
public
String
gremlinCompOp
(
Expressions
.
ComparisonExpression
op
)
{
return
GraphPersistenceStrategies$class
.
gremlinCompOp
(
this
,
op
);
}
@Override
public
String
gremlinPrimitiveOp
(
Expressions
.
ComparisonExpression
op
)
{
return
GraphPersistenceStrategies$class
.
gremlinPrimitiveOp
(
this
,
op
);
}
@Override
public
String
loopObjectExpression
(
IDataType
<?>
dataType
)
{
return
GraphPersistenceStrategies$class
.
loopObjectExpression
(
this
,
dataType
);
public
AtlasEdgeDirection
instanceToTraitEdgeDirection
()
{
return
AtlasEdgeDirection
.
OUT
;
}
@Override
public
String
instanceToTraitEdgeDirection
()
{
return
"out"
;
}
@Override
public
String
traitToInstanceEdgeDirection
()
{
return
"in"
;
public
AtlasEdgeDirection
traitToInstanceEdgeDirection
()
{
return
AtlasEdgeDirection
.
IN
;
}
@Override
...
...
@@ -247,33 +227,28 @@ public class DefaultGraphPersistenceStrategy implements GraphPersistenceStrategi
}
@Override
public
scala
.
collection
.
Seq
<
String
>
typeTestExpression
(
String
typeName
,
IntSequence
intSeq
)
{
return
GraphPersistenceStrategies$class
.
typeTestExpression
(
this
,
typeName
,
intSeq
);
}
@Override
public
boolean
collectTypeInstancesIntoVar
()
{
return
GraphPersistenceStrategies$class
.
collectTypeInstancesIntoVar
(
this
);
}
@Override
public
boolean
addGraphVertexPrefix
(
scala
.
collection
.
Traversable
<
String
>
preStatements
)
{
public
boolean
addGraphVertexPrefix
(
scala
.
collection
.
Traversable
<
GroovyExpression
>
preStatements
)
{
return
GraphPersistenceStrategies$class
.
addGraphVertexPrefix
(
this
,
preStatements
);
}
@Override
public
GremlinVersion
getSupportedGremlinVersion
()
{
return
GraphPersistenceStrategies$class
.
getSupportedGremlinVersion
(
this
);
}
@Override
public
String
generatePersisentToLogicalConversionExpression
(
String
expr
,
IDataType
<?>
t
)
{
public
GroovyExpression
generatePersisentToLogicalConversionExpression
(
GroovyExpression
expr
,
IDataType
<?>
t
)
{
return
GraphPersistenceStrategies$class
.
generatePersisentToLogicalConversionExpression
(
this
,
expr
,
t
);
}
@Override
public
String
initialQueryCondition
(
)
{
return
GraphPersistenceStrategies$class
.
initialQueryCondition
(
this
);
public
GroovyExpression
addInitialQueryCondition
(
GroovyExpression
expr
)
{
return
GraphPersistenceStrategies$class
.
addInitialQueryCondition
(
this
,
expr
);
}
@Override
...
...
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
0 → 100644
View file @
69af0ae7
/**
* 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.List
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.groovy.ClosureExpression
;
import
org.apache.atlas.groovy.ComparisonExpression
;
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.ListExpression
;
import
org.apache.atlas.groovy.LiteralExpression
;
import
org.apache.atlas.groovy.LogicalExpression
;
import
org.apache.atlas.groovy.RangeExpression
;
import
org.apache.atlas.groovy.TernaryOperatorExpression
;
import
org.apache.atlas.groovy.ComparisonExpression.ComparisonOperator
;
import
org.apache.atlas.groovy.LogicalExpression.LogicalOperator
;
import
org.apache.atlas.query.GraphPersistenceStrategies
;
import
org.apache.atlas.query.TypeUtils.FieldInfo
;
import
org.apache.atlas.typesystem.types.IDataType
;
/**
* Generates gremlin query expressions using Gremlin 2 syntax.
*
*/
public
class
Gremlin2ExpressionFactory
extends
GremlinExpressionFactory
{
private
static
final
String
LOOP_METHOD
=
"loop"
;
private
static
final
String
CONTAINS
=
"contains"
;
private
static
final
String
LOOP_COUNT_FIELD
=
"loops"
;
private
static
final
String
PATH_FIELD
=
"path"
;
private
static
final
String
ENABLE_PATH_METHOD
=
"enablePath"
;
private
static
final
String
BACK_METHOD
=
"back"
;
@Override
public
GroovyExpression
generateLogicalExpression
(
GroovyExpression
parent
,
String
operator
,
List
<
GroovyExpression
>
operands
)
{
return
new
FunctionCallExpression
(
parent
,
operator
,
operands
);
}
@Override
public
GroovyExpression
generateBackReferenceExpression
(
GroovyExpression
parent
,
boolean
inSelect
,
String
alias
)
{
if
(
inSelect
)
{
return
getFieldInSelect
();
}
else
{
return
new
FunctionCallExpression
(
parent
,
BACK_METHOD
,
new
LiteralExpression
(
alias
));
}
}
@Override
public
GroovyExpression
getLoopExpressionParent
(
GroovyExpression
inputQry
)
{
return
inputQry
;
}
@Override
public
GroovyExpression
generateLoopExpression
(
GroovyExpression
parent
,
GraphPersistenceStrategies
s
,
IDataType
dataType
,
GroovyExpression
loopExpr
,
String
alias
,
Integer
times
)
{
GroovyExpression
emitExpr
=
generateLoopEmitExpression
(
s
,
dataType
);
//note that in Gremlin 2 (unlike Gremlin 3), the parent is not explicitly used. It is incorporated
//in the loopExpr.
GroovyExpression
whileFunction
=
null
;
if
(
times
!=
null
)
{
GroovyExpression
loopsExpr
=
new
FieldExpression
(
getItVariable
(),
LOOP_COUNT_FIELD
);
GroovyExpression
timesExpr
=
new
LiteralExpression
(
times
);
whileFunction
=
new
ClosureExpression
(
new
ComparisonExpression
(
loopsExpr
,
ComparisonOperator
.
LESS_THAN
,
timesExpr
));
}
else
{
GroovyExpression
pathExpr
=
new
FieldExpression
(
getItVariable
(),
PATH_FIELD
);
GroovyExpression
itObjectExpr
=
getCurrentObjectExpression
();
GroovyExpression
pathContainsExpr
=
new
FunctionCallExpression
(
pathExpr
,
CONTAINS
,
itObjectExpr
);
whileFunction
=
new
ClosureExpression
(
new
TernaryOperatorExpression
(
pathContainsExpr
,
LiteralExpression
.
FALSE
,
LiteralExpression
.
TRUE
));
}
GroovyExpression
emitFunction
=
new
ClosureExpression
(
emitExpr
);
GroovyExpression
loopCall
=
new
FunctionCallExpression
(
loopExpr
,
LOOP_METHOD
,
new
LiteralExpression
(
alias
),
whileFunction
,
emitFunction
);
return
new
FunctionCallExpression
(
loopCall
,
ENABLE_PATH_METHOD
);
}
@Override
public
GroovyExpression
typeTestExpression
(
GraphPersistenceStrategies
s
,
String
typeName
,
GroovyExpression
itRef
)
{
GroovyExpression
typeAttrExpr
=
new
FieldExpression
(
itRef
,
s
.
typeAttributeName
());
GroovyExpression
superTypeAttrExpr
=
new
FieldExpression
(
itRef
,
s
.
superTypeAttributeName
());
GroovyExpression
typeNameExpr
=
new
LiteralExpression
(
typeName
);
GroovyExpression
typeMatchesExpr
=
new
ComparisonExpression
(
typeAttrExpr
,
ComparisonOperator
.
EQUALS
,
typeNameExpr
);
GroovyExpression
isSuperTypeExpr
=
new
FunctionCallExpression
(
superTypeAttrExpr
,
CONTAINS
,
typeNameExpr
);
GroovyExpression
hasSuperTypeAttrExpr
=
superTypeAttrExpr
;
GroovyExpression
superTypeMatchesExpr
=
new
TernaryOperatorExpression
(
hasSuperTypeAttrExpr
,
isSuperTypeExpr
,
LiteralExpression
.
FALSE
);
return
new
LogicalExpression
(
typeMatchesExpr
,
LogicalOperator
.
OR
,
superTypeMatchesExpr
);
}
@Override
public
GroovyExpression
generateSelectExpression
(
GroovyExpression
parent
,
List
<
LiteralExpression
>
sourceNames
,
List
<
GroovyExpression
>
srcExprs
)
{
GroovyExpression
srcNamesExpr
=
new
ListExpression
(
sourceNames
);
List
<
GroovyExpression
>
selectArgs
=
new
ArrayList
<>();
selectArgs
.
add
(
srcNamesExpr
);
for
(
GroovyExpression
expr
:
srcExprs
)
{
selectArgs
.
add
(
new
ClosureExpression
(
expr
));
}
return
new
FunctionCallExpression
(
parent
,
SELECT_METHOD
,
selectArgs
);
}
@Override
public
GroovyExpression
generateFieldExpression
(
GroovyExpression
parent
,
FieldInfo
fInfo
,
String
propertyName
,
boolean
inSelect
)
{
return
new
FieldExpression
(
parent
,
propertyName
);
}
@Override
public
GroovyExpression
generateHasExpression
(
GraphPersistenceStrategies
s
,
GroovyExpression
parent
,
String
propertyName
,
String
symbol
,
GroovyExpression
requiredValue
,
FieldInfo
fInfo
)
throws
AtlasException
{
GroovyExpression
op
=
gremlin2CompOp
(
symbol
);
GroovyExpression
propertyNameExpr
=
new
LiteralExpression
(
propertyName
);
return
new
FunctionCallExpression
(
parent
,
HAS_METHOD
,
propertyNameExpr
,
op
,
requiredValue
);
}
private
GroovyExpression
gremlin2CompOp
(
String
op
)
throws
AtlasException
{
GroovyExpression
tExpr
=
new
IdentifierExpression
(
"T"
);
if
(
op
.
equals
(
"="
))
{
return
new
FieldExpression
(
tExpr
,
"eq"
);
}
if
(
op
.
equals
(
"!="
))
{
return
new
FieldExpression
(
tExpr
,
"neq"
);
}
if
(
op
.
equals
(
">"
))
{
return
new
FieldExpression
(
tExpr
,
"gt"
);
}
if
(
op
.
equals
(
">="
))
{
return
new
FieldExpression
(
tExpr
,
"gte"
);
}
if
(
op
.
equals
(
"<"
))
{
return
new
FieldExpression
(
tExpr
,
"lt"
);
}
if
(
op
.
equals
(
"<="
))
{
return
new
FieldExpression
(
tExpr
,
"lte"
);
}
throw
new
AtlasException
(
"Comparison operator "
+
op
+
" not supported in Gremlin"
);
}
@Override
protected
GroovyExpression
initialExpression
(
GraphPersistenceStrategies
s
,
GroovyExpression
varExpr
)
{
return
new
FunctionCallExpression
(
varExpr
,
"_"
);
}
@Override
public
GroovyExpression
generateLimitExpression
(
GroovyExpression
parent
,
int
offset
,
int
totalRows
)
{
return
new
RangeExpression
(
parent
,
offset
,
totalRows
);
}
@Override
public
List
<
GroovyExpression
>
getOrderFieldParents
()
{
GroovyExpression
itExpr
=
getItVariable
();
List
<
GroovyExpression
>
result
=
new
ArrayList
<>(
2
);
result
.
add
(
new
FieldExpression
(
itExpr
,
"a"
));
result
.
add
(
new
FieldExpression
(
itExpr
,
"b"
));
return
result
;
}
@Override
public
GroovyExpression
generateOrderByExpression
(
GroovyExpression
parent
,
List
<
GroovyExpression
>
translatedOrderBy
,
boolean
isAscending
)
{
GroovyExpression
itExpr
=
getItVariable
();
GroovyExpression
aPropertyExpr
=
translatedOrderBy
.
get
(
0
);
GroovyExpression
bPropertyExpr
=
translatedOrderBy
.
get
(
1
);
GroovyExpression
aPropertyNotNull
=
new
ComparisonExpression
(
aPropertyExpr
,
ComparisonOperator
.
NOT_EQUALS
,
LiteralExpression
.
NULL
);
GroovyExpression
bPropertyNotNull
=
new
ComparisonExpression
(
bPropertyExpr
,
ComparisonOperator
.
NOT_EQUALS
,
LiteralExpression
.
NULL
);
GroovyExpression
aCondition
=
new
TernaryOperatorExpression
(
aPropertyNotNull
,
new
FunctionCallExpression
(
aPropertyExpr
,
TO_LOWER_CASE_METHOD
),
aPropertyExpr
);
GroovyExpression
bCondition
=
new
TernaryOperatorExpression
(
bPropertyNotNull
,
new
FunctionCallExpression
(
bPropertyExpr
,
TO_LOWER_CASE_METHOD
),
bPropertyExpr
);
GroovyExpression
comparisonFunction
=
null
;
if
(
isAscending
)
{
comparisonFunction
=
new
ComparisonOperatorExpression
(
aCondition
,
bCondition
);
}
else
{
comparisonFunction
=
new
ComparisonOperatorExpression
(
bCondition
,
aCondition
);
}
return
new
FunctionCallExpression
(
parent
,
ORDER_METHOD
,
new
ClosureExpression
(
comparisonFunction
));
}
@Override
public
GroovyExpression
getAnonymousTraversalExpression
()
{
return
new
FunctionCallExpression
(
"_"
);
}
@Override
public
GroovyExpression
getFieldInSelect
()
{
return
getItVariable
();
}
}
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
0 → 100644
View file @
69af0ae7
/**
* 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.List
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.groovy.CastExpression
;
import
org.apache.atlas.groovy.ClosureExpression
;
import
org.apache.atlas.groovy.ComparisonExpression
;
import
org.apache.atlas.groovy.ComparisonOperatorExpression
;
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.TypeCoersionExpression
;
import
org.apache.atlas.groovy.ComparisonExpression.ComparisonOperator
;
import
org.apache.atlas.groovy.LogicalExpression.LogicalOperator
;
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
WHERE_METHOD
=
"where"
;
private
static
final
String
TO_STRING_METHOD
=
"toString"
;
@Override
public
GroovyExpression
generateLogicalExpression
(
GroovyExpression
parent
,
String
operator
,
List
<
GroovyExpression
>
operands
)
{
if
(
operands
.
size
()
==
1
)
{
// gremlin 3 treats one element expressions as 'false'. Avoid
// creating a boolean expression in this case. Inline the expression
// note: we can't simply omit it, since it will cause us to traverse
// the edge!
// use 'where' instead
GroovyExpression
expr
=
operands
.
get
(
0
);
// if child is a back expression, that expression becomes an
// argument to where
return
new
FunctionCallExpression
(
parent
,
WHERE_METHOD
,
expr
);
}
else
{
// Gremlin 3 does not support _() syntax
//
return
new
FunctionCallExpression
(
parent
,
operator
,
operands
);
}
}
@Override
public
GroovyExpression
generateBackReferenceExpression
(
GroovyExpression
parent
,
boolean
inSelect
,
String
alias
)
{
if
(
inSelect
)
{
return
getFieldInSelect
();
}
else
{
return
new
FunctionCallExpression
(
parent
,
SELECT_METHOD
,
new
LiteralExpression
(
alias
));
}
}
@Override
public
GroovyExpression
typeTestExpression
(
GraphPersistenceStrategies
s
,
String
typeName
,
GroovyExpression
itRef
)
{
LiteralExpression
typeAttrExpr
=
new
LiteralExpression
(
s
.
typeAttributeName
());
LiteralExpression
superTypeAttrExpr
=
new
LiteralExpression
(
s
.
superTypeAttributeName
());
LiteralExpression
typeNameExpr
=
new
LiteralExpression
(
typeName
);
FunctionCallExpression
result
=
new
FunctionCallExpression
(
HAS_METHOD
,
typeAttrExpr
,
new
FunctionCallExpression
(
EQ_METHOD
,
typeNameExpr
));
result
=
new
FunctionCallExpression
(
result
,
"or"
);
result
=
new
FunctionCallExpression
(
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
(
parent
,
REPEAT_METHOD
,
loopExpr
);
if
(
times
!=
null
)
{
GroovyExpression
timesExpr
=
new
LiteralExpression
(
times
);
result
=
new
FunctionCallExpression
(
result
,
TIMES_METHOD
,
timesExpr
);
}
result
=
new
FunctionCallExpression
(
result
,
EMIT_METHOD
,
emitExpr
);
return
result
;
}
@Override
public
GroovyExpression
getLoopExpressionParent
(
GroovyExpression
inputQry
)
{
GroovyExpression
curTraversal
=
new
IdentifierExpression
(
"__"
);
return
curTraversal
;
}
@Override
public
GroovyExpression
generateSelectExpression
(
GroovyExpression
parent
,
List
<
LiteralExpression
>
sourceNames
,
List
<
GroovyExpression
>
srcExprs
)
{
FunctionCallExpression
result
=
new
FunctionCallExpression
(
parent
,
SELECT_METHOD
,
sourceNames
);
for
(
GroovyExpression
expr
:
srcExprs
)
{
GroovyExpression
closure
=
new
ClosureExpression
(
expr
);
GroovyExpression
castClosure
=
new
TypeCoersionExpression
(
closure
,
FUNCTION_CLASS
);
result
=
new
FunctionCallExpression
(
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
);
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
(
parent
,
VALUES_METHOD
,
propertyNameExpr
);
if
(
graph
.
isPropertyValueConversionNeeded
(
attrType
))
{
GroovyExpression
toConvert
=
new
FunctionCallExpression
(
getItVariable
(),
GET_METHOD
);
GroovyExpression
conversionFunction
=
graph
.
generatePersisentToLogicalConversionExpression
(
toConvert
,
attrType
);
return
new
FunctionCallExpression
(
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
(
parent
,
FILTER_METHOD
,
filterFunction
);
}
else
{
GroovyExpression
valueMatches
=
new
FunctionCallExpression
(
getComparisonFunction
(
symbol
),
requiredValue
);
return
new
FunctionCallExpression
(
parent
,
HAS_METHOD
,
propertNameExpr
,
valueMatches
);
}
}
@Override
protected
GroovyExpression
initialExpression
(
GraphPersistenceStrategies
s
,
GroovyExpression
varExpr
)
{
// 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
=
getGraph
();
GroovyExpression
varRefExpr
=
new
TypeCoersionExpression
(
varExpr
,
OBJECT_ARRAY_CLASS
);
FunctionCallExpression
expr
=
new
FunctionCallExpression
(
gExpr
,
V_METHOD
,
varRefExpr
);
return
s
.
addInitialQueryCondition
(
expr
);
}
@Override
public
GroovyExpression
generateLimitExpression
(
GroovyExpression
parent
,
int
offset
,
int
totalRows
)
{
return
new
FunctionCallExpression
(
parent
,
RANGE_METHOD
,
new
LiteralExpression
(
offset
),
new
LiteralExpression
(
totalRows
));
}
@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
orderByClause
=
translatedOrderBy
.
get
(
0
);
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"
);
return
new
FunctionCallExpression
(
new
FunctionCallExpression
(
parent
,
ORDER_METHOD
),
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
);
}
}
This diff is collapsed.
Click to expand it.
repository/src/main/java/org/apache/atlas/gremlin/GremlinExpressionFactory.java
0 → 100644
View file @
69af0ae7
/**
* 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.List
;
import
org.apache.atlas.AtlasException
;
import
org.apache.atlas.groovy.ArithmeticExpression
;
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.TypeCoersionExpression
;
import
org.apache.atlas.groovy.VariableAssignmentExpression
;
import
org.apache.atlas.groovy.ArithmeticExpression.ArithmeticOperator
;
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
;
/**
* 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"
;
private
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
FILL_METHOD
=
"fill"
;
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"
;
public
static
final
GremlinExpressionFactory
INSTANCE
=
AtlasGraphProvider
.
getGraphInstance
()
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
THREE
?
new
Gremlin3ExpressionFactory
()
:
new
Gremlin2ExpressionFactory
();
/**
* 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
;
/**
* Generates a limit expression
*
* @param parent
* @param offset
* @param totalRows
* @return
*/
public
abstract
GroovyExpression
generateLimitExpression
(
GroovyExpression
parent
,
int
offset
,
int
totalRows
);
/**
* Generates an order by expression
*
* @param parent
* @param translatedOrderBy
* @param isAscending
* @return
*/
public
abstract
GroovyExpression
generateOrderByExpression
(
GroovyExpression
parent
,
List
<
GroovyExpression
>
translatedOrderBy
,
boolean
isAscending
);
/**
* 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
();
/**
* Returns an expression representing
*
* @return
*/
public
abstract
GroovyExpression
getFieldInSelect
();
/**
* Generates the expression the serves as the root of the Gremlin query.
* @param s
* @param varExpr variable containing the vertices to traverse
* @return
*/
protected
abstract
GroovyExpression
initialExpression
(
GraphPersistenceStrategies
s
,
GroovyExpression
varExpr
);
/**
* 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, the vertices are put into a variable whose name is geneated 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
)
{
if
(
s
.
collectTypeInstancesIntoVar
())
{
return
typeTestExpressionMultiStep
(
s
,
typeName
,
intSeq
);
}
else
{
return
typeTestExpressionUsingFilter
(
s
,
parent
,
typeName
);
}
}
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
(
s
,
varExpr
));
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
(
parent
,
HAS_METHOD
,
new
LiteralExpression
(
fieldName
));
}
/**
* Generates a path expression
*
* @param parent
* @return
*/
public
GroovyExpression
generatePathExpression
(
GroovyExpression
parent
)
{
return
new
FunctionCallExpression
(
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
(
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
(
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
(
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
);
}
protected
GroovyExpression
getItVariable
()
{
return
new
IdentifierExpression
(
IT_VARIABLE
);
}
protected
GroovyExpression
getAllVerticesExpr
()
{
GroovyExpression
gExpr
=
getGraph
();
return
new
FunctionCallExpression
(
gExpr
,
V_METHOD
);
}
protected
IdentifierExpression
getGraph
()
{
return
new
IdentifierExpression
(
G_VARIABLE
);
}
protected
GroovyExpression
getCurrentObjectExpression
()
{
return
new
FieldExpression
(
getItVariable
(),
OBJECT_FIELD
);
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
repository/src/main/scala/org/apache/atlas/query/GraphPersistenceStrategies.scala
View file @
69af0ae7
...
...
@@ -21,23 +21,20 @@ package org.apache.atlas.query
import
java.util
import
java.util.Date
import
scala.collection.JavaConversions._
import
scala.collection.JavaConversions.seqAsJavaList
import
scala.language.existentials
import
org.apache.atlas.
query.Expressions.
{
ComparisonExpression
,
ExpressionException
}
import
org.apache.atlas.
groovy.GroovyExpression
import
org.apache.atlas.query.TypeUtils.FieldInfo
import
org.apache.atlas.repository.graph.
{
GraphHelper
,
GraphBackedMetadataRepository
}
import
org.apache.atlas.repository.RepositoryException
import
org.apache.atlas.repository.graph.GraphHelper
import
org.apache.atlas.repository.graphdb._
import
org.apache.atlas.typesystem.
persistence.Id
import
org.apache.atlas.typesystem.
types.DataTypes._
import
org.apache.atlas.typesystem.
ITypedInstance
import
org.apache.atlas.typesystem.
ITypedReferenceableInstance
import
org.apache.atlas.typesystem.persistence.Id
import
org.apache.atlas.typesystem.types._
import
org.apache.atlas.typesystem.
{
ITypedInstance
,
ITypedReferenceableInstance
}
import
scala.collection.JavaConversions._
import
scala.collection.mutable
import
scala.collection.mutable.ArrayBuffer
import
org.apache.atlas.typesystem.types.DataTypes._
/**
* Represents the Bridge between the QueryProcessor and the Graph Persistence scheme used.
...
...
@@ -47,19 +44,19 @@ import scala.collection.mutable.ArrayBuffer
* - how are attribute names mapped to Property Keys in Vertices.
*
* This is a work in progress.
*
*
*/
trait
GraphPersistenceStrategies
{
@throws
(
classOf
[
RepositoryException
])
def
getGraph
()
:
AtlasGraph
[
_
,
_
]
def
getSupportedGremlinVersion
()
:
GremlinVersion
=
getGraph
().
getSupportedGremlinVersion
;
def
generatePersisentToLogicalConversionExpression
(
expr
:
String
,
t
:
IDataType
[
_
])
:
String
=
getGraph
().
generatePersisentToLogicalConversionExpression
(
expr
,
t
);
def
generatePersisentToLogicalConversionExpression
(
expr
:
GroovyExpression
,
t
:
IDataType
[
_
])
:
GroovyExpression
=
getGraph
().
generatePersisentToLogicalConversionExpression
(
expr
,
t
);
def
isPropertyValueConversionNeeded
(
attrType
:
IDataType
[
_
])
:
Boolean
=
getGraph
().
isPropertyValueConversionNeeded
(
attrType
);
def
initialQueryCondition
=
if
(
getGraph
().
requiresInitialIndexedPredicate
())
{
s
""".${getGraph().getInitialIndexedPredicate}"""
}
else
{
""
};
def
addInitialQueryCondition
(
parent
:
GroovyExpression
)
:
GroovyExpression
=
if
(
getGraph
().
requiresInitialIndexedPredicate
())
{
getGraph
().
getInitialIndexedPredicate
(
parent
)
}
else
{
parent
};
/**
* Name of attribute used to store typeName in vertex
*/
...
...
@@ -87,11 +84,12 @@ trait GraphPersistenceStrategies {
def
traitLabel
(
cls
:
IDataType
[
_
],
traitName
:
String
)
:
String
def
instanceToTraitEdgeDirection
:
String
=
"out"
def
traitToInstanceEdgeDirection
=
instanceToTraitEdgeDirection
match
{
case
"out"
=>
"in"
case
"in"
=>
"out"
case
x
=>
x
def
instanceToTraitEdgeDirection
:
AtlasEdgeDirection
=
AtlasEdgeDirection
.
OUT
;
def
traitToInstanceEdgeDirection
:
AtlasEdgeDirection
=
instanceToTraitEdgeDirection
match
{
case
AtlasEdgeDirection
.
OUT
=>
AtlasEdgeDirection
.
IN
;
case
AtlasEdgeDirection
.
IN
=>
AtlasEdgeDirection
.
OUT
;
case
x
=>
AtlasEdgeDirection
.
IN
;
}
/**
...
...
@@ -115,27 +113,6 @@ trait GraphPersistenceStrategies {
case
FieldInfo
(
dataType
,
null
,
null
,
traitName
)
=>
traitLabel
(
dataType
,
traitName
)
}
def
fieldPrefixInSelect
()
:
String
=
{
if
(
getSupportedGremlinVersion
()
==
GremlinVersion
.
THREE
)
{
//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.
"((it as Vertex[]) as List<Vertex>).last()"
}
else
{
"it"
}
}
/**
* extract the Id from a Vertex.
* @param dataTypeNm the dataType of the instance that the given vertex represents
...
...
@@ -146,50 +123,7 @@ trait GraphPersistenceStrategies {
def
constructInstance
[
U
](
dataType
:
IDataType
[
U
],
v
:
java.lang.Object
)
:
U
def
gremlinCompOp
(
op
:
ComparisonExpression
)
=
{
if
(
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
gremlin2CompOp
(
op
);
}
else
{
gremlin3CompOp
(
op
);
}
}
def
gremlinPrimitiveOp
(
op
:
ComparisonExpression
)
=
op
.
symbol
match
{
case
"="
=>
"=="
case
"!="
=>
"!="
case
">"
=>
">"
case
">="
=>
">="
case
"<"
=>
"<"
case
"<="
=>
"<="
case
_
=>
throw
new
ExpressionException
(
op
,
"Comparison operator not supported in Gremlin"
)
}
private
def
gremlin2CompOp
(
op
:
ComparisonExpression
)
=
op
.
symbol
match
{
case
"="
=>
"T.eq"
case
"!="
=>
"T.neq"
case
">"
=>
"T.gt"
case
">="
=>
"T.gte"
case
"<"
=>
"T.lt"
case
"<="
=>
"T.lte"
case
_
=>
throw
new
ExpressionException
(
op
,
"Comparison operator not supported in Gremlin"
)
}
private
def
gremlin3CompOp
(
op
:
ComparisonExpression
)
=
op
.
symbol
match
{
case
"="
=>
"eq"
case
"!="
=>
"neq"
case
">"
=>
"gt"
case
">="
=>
"gte"
case
"<"
=>
"lt"
case
"<="
=>
"lte"
case
_
=>
throw
new
ExpressionException
(
op
,
"Comparison operator not supported in Gremlin"
)
}
def
loopObjectExpression
(
dataType
:
IDataType
[
_
])
=
{
_typeTestExpression
(
dataType
.
getName
,
"it.object"
)
}
def
addGraphVertexPrefix
(
preStatements
:
Traversable
[
String
])
=
!
collectTypeInstancesIntoVar
def
addGraphVertexPrefix
(
preStatements
:
Traversable
[
GroovyExpression
])
=
!
collectTypeInstancesIntoVar
/**
* Controls behavior of how instances of a Type are discovered.
...
...
@@ -213,76 +147,14 @@ trait GraphPersistenceStrategies {
*/
def
collectTypeInstancesIntoVar
=
true
def
typeTestExpression
(
typeName
:
String
,
intSeq
:
IntSequence
)
:
Seq
[
String
]
=
{
if
(
collectTypeInstancesIntoVar
)
typeTestExpressionMultiStep
(
typeName
,
intSeq
)
else
typeTestExpressionUsingFilter
(
typeName
)
}
private
def
typeTestExpressionUsingFilter
(
typeName
:
String
)
:
Seq
[
String
]
=
{
Seq
(
s
"""filter${_typeTestExpression(typeName, "it")}"""
)
}
/**
* type test expression that ends up in the emit clause in
* loop/repeat steps and a few other places
*/
private
def
_typeTestExpression
(
typeName
:
String
,
itRef
:
String
)
:
String
=
{
if
(
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
s
"""{(${itRef}.'${typeAttributeName}' == '${typeName}') |
| (${itRef}.'${superTypeAttributeName}' ?
| ${itRef}.'${superTypeAttributeName}'.contains('${typeName}') : false)}"""
.
stripMargin
.
replace
(
System
.
getProperty
(
"line.separator"
),
""
)
}
else
{
//gremlin 3
s
"""has('${typeAttributeName}',eq('${typeName}')).or().has('${superTypeAttributeName}',eq('${typeName}'))"""
}
}
private
def
propertyValueSet
(
vertexRef
:
String
,
attrName
:
String
)
:
String
=
{
s
"""org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils.set(${vertexRef}.values('${attrName})"""
}
private
def
typeTestExpressionMultiStep
(
typeName
:
String
,
intSeq
:
IntSequence
)
:
Seq
[
String
]
=
{
val
varName
=
s
"_var_${intSeq.next}"
Seq
(
newSetVar
(
varName
),
fillVarWithTypeInstances
(
typeName
,
varName
),
fillVarWithSubTypeInstances
(
typeName
,
varName
),
if
(
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
s
"$varName._()"
}
else
{
//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[])"
s
"g.V(${varName} as Object[])${initialQueryCondition}"
}
)
}
private
def
newSetVar
(
varName
:
String
)
=
s
"def $varName = [] as Set"
private
def
fillVarWithTypeInstances
(
typeName
:
String
,
fillVar
:
String
)
=
{
s
"""g.V().has("${typeAttributeName}", "${typeName}").fill($fillVar)"""
}
private
def
fillVarWithSubTypeInstances
(
typeName
:
String
,
fillVar
:
String
)
=
{
s
"""g.V().has("${superTypeAttributeName}", "${typeName}").fill($fillVar)"""
}
}
import
scala.language.existentials
;
import
org.apache.atlas.repository.RepositoryException
import
org.apache.atlas.repository.RepositoryException
import
org.apache.atlas.repository.RepositoryException
import
org.apache.atlas.repository.RepositoryException
case
class
GraphPersistenceStrategy1
(
g
:
AtlasGraph
[
_
,
_
])
extends
GraphPersistenceStrategies
{
...
...
@@ -293,8 +165,8 @@ case class GraphPersistenceStrategy1(g: AtlasGraph[_,_]) extends GraphPersistenc
override
def
getGraph
()
:
AtlasGraph
[
_
,
_
]
=
{
return
g
;
}
}
def
edgeLabel
(
dataType
:
IDataType
[
_
],
aInfo
:
AttributeInfo
)
=
s
"__${dataType.getName}.${aInfo.name}"
def
edgeLabel
(
propertyName
:
String
)
=
s
"__${propertyName}"
...
...
@@ -458,8 +330,6 @@ case class GraphPersistenceStrategy1(g: AtlasGraph[_,_]) extends GraphPersistenc
}
}
private
def
mapVertexToCollectionEntry
(
instanceVertex
:
AtlasVertex
[
_
,
_
],
attributeInfo
:
AttributeInfo
,
elementType
:
IDataType
[
_
],
i
:
ITypedInstance
,
value
:
Any
)
:
Any
=
{
elementType
.
getTypeCategory
match
{
case
DataTypes
.
TypeCategory
.
PRIMITIVE
=>
value
...
...
@@ -474,5 +344,6 @@ case class GraphPersistenceStrategy1(g: AtlasGraph[_,_]) extends GraphPersistenc
throw
new
UnsupportedOperationException
(
s
"load for ${attributeInfo.dataType()} not supported"
)
}
}
}
This diff is collapsed.
Click to expand it.
repository/src/main/scala/org/apache/atlas/query/GremlinQuery.scala
View file @
69af0ae7
...
...
@@ -18,30 +18,61 @@
package
org.apache.atlas.query
import
java.lang.Boolean
import
java.lang.Byte
import
java.lang.Double
import
java.lang.Float
import
java.lang.Integer
import
java.lang.Long
import
java.lang.Short
import
java.util.ArrayList
import
scala.collection.JavaConversions.asScalaBuffer
import
scala.collection.JavaConversions.bufferAsJavaList
import
scala.collection.mutable
import
scala.collection.mutable.ArrayBuffer
import
org.apache.atlas.query.TypeUtils.FieldInfo
;
import
org.apache.atlas.query.Expressions._
import
org.apache.atlas.repository.graphdb.GremlinVersion
import
org.apache.atlas.gremlin.GremlinExpressionFactory
import
org.apache.atlas.groovy.CastExpression
import
org.apache.atlas.groovy.CodeBlockExpression
import
org.apache.atlas.groovy.FunctionCallExpression
import
org.apache.atlas.groovy.GroovyExpression
import
org.apache.atlas.groovy.GroovyGenerationContext
import
org.apache.atlas.groovy.IdentifierExpression
import
org.apache.atlas.groovy.ListExpression
import
org.apache.atlas.groovy.LiteralExpression
import
org.apache.atlas.query.Expressions.AliasExpression
import
org.apache.atlas.query.Expressions.ArithmeticExpression
import
org.apache.atlas.query.Expressions.BackReference
import
org.apache.atlas.query.Expressions.ClassExpression
import
org.apache.atlas.query.Expressions.ComparisonExpression
import
org.apache.atlas.query.Expressions.Expression
import
org.apache.atlas.query.Expressions.ExpressionException
import
org.apache.atlas.query.Expressions.FieldExpression
import
org.apache.atlas.query.Expressions.FilterExpression
import
org.apache.atlas.query.Expressions.InstanceExpression
import
org.apache.atlas.query.Expressions.LimitExpression
import
org.apache.atlas.query.Expressions.ListLiteral
import
org.apache.atlas.query.Expressions.Literal
import
org.apache.atlas.query.Expressions.LogicalExpression
import
org.apache.atlas.query.Expressions.LoopExpression
import
org.apache.atlas.query.Expressions.OrderExpression
import
org.apache.atlas.query.Expressions.PathExpression
import
org.apache.atlas.query.Expressions.SelectExpression
import
org.apache.atlas.query.Expressions.TraitExpression
import
org.apache.atlas.query.Expressions.TraitInstanceExpression
import
org.apache.atlas.query.Expressions.hasFieldLeafExpression
import
org.apache.atlas.query.Expressions.hasFieldUnaryExpression
import
org.apache.atlas.query.Expressions.id
import
org.apache.atlas.query.Expressions.isTraitLeafExpression
import
org.apache.atlas.query.Expressions.isTraitUnaryExpression
import
org.apache.atlas.repository.RepositoryException
import
org.apache.atlas.repository.graphdb.AtlasEdgeDirection
import
org.apache.atlas.typesystem.types.DataTypes
import
org.apache.atlas.typesystem.types.DataTypes.TypeCategory
import
org.apache.atlas.typesystem.types.IDataType
import
org.apache.commons.lang.StringEscapeUtils
import
org.apache.atlas.typesystem.types.TypeSystem
import
org.apache.atlas.typesystem.types.AttributeInfo
import
org.joda.time.format.ISODateTimeFormat
import
org.apache.atlas.typesystem.types.DataTypes.BigDecimalType
import
org.apache.atlas.typesystem.types.DataTypes.ByteType
import
org.apache.atlas.typesystem.types.DataTypes.BooleanType
import
org.apache.atlas.typesystem.types.DataTypes.DateType
import
org.apache.atlas.typesystem.types.DataTypes.BigIntegerType
import
org.apache.atlas.typesystem.types.DataTypes.IntType
import
org.apache.atlas.typesystem.types.DataTypes.StringType
import
org.apache.atlas.typesystem.types.DataTypes.LongType
import
org.apache.atlas.typesystem.types.DataTypes.DoubleType
import
org.apache.atlas.typesystem.types.DataTypes.FloatType
import
org.apache.atlas.typesystem.types.DataTypes.ShortType
trait
IntSequence
{
def
next
:
Int
...
...
@@ -127,7 +158,7 @@ trait SelectExpressionHandling {
/**
* For each Output Column in the SelectExpression compute the ArrayList(Src) this maps to and the position within
* this list.
*
*
* @param sel
* @return
*/
...
...
@@ -151,8 +182,8 @@ class GremlinTranslator(expr: Expression,
gPersistenceBehavior
:
GraphPersistenceStrategies
)
extends
SelectExpressionHandling
{
val
preStatements
=
ArrayBuffer
[
String
]()
val
postStatements
=
ArrayBuffer
[
String
]()
val
preStatements
=
ArrayBuffer
[
GroovyExpression
]()
val
postStatements
=
ArrayBuffer
[
GroovyExpression
]()
val
wrapAndRule
:
PartialFunction
[
Expression
,
Expression
]
=
{
case
f
:
FilterExpression
if
!f.condExpr.isInstanceOf
[
LogicalExpression
]
=>
...
...
@@ -216,351 +247,287 @@ class GremlinTranslator(expr: Expression,
}
}
def
typeTestExpression
(
typeName
:
String
)
:
String
=
{
val
stats
=
gPersistenceBehavior
.
typeTestExpression
(
escape
(
typeName
),
counter
)
def
typeTestExpression
(
parent
:
GroovyExpression
,
typeName
:
String
)
:
GroovyExpression
=
{
val
stats
=
GremlinExpressionFactory
.
INSTANCE
.
generateTypeTestExpression
(
gPersistenceBehavior
,
parent
,
typeName
,
counter
)
preStatements
++=
stats
.
init
stats
.
last
}
def
escape
(
str
:
String
)
:
String
=
{
if
(
str
!=
null
)
{
return
str
.
replace
(
"\""
,
"\\\""
).
replace
(
"$"
,
"\\$"
);
}
str
val
QUOTE
=
"\""
;
private
def
cleanStringLiteral
(
l
:
Literal
[
_
])
:
String
=
{
return
l
.
toString
.
stripPrefix
(
QUOTE
).
stripSuffix
(
QUOTE
);
}
private
def
genQuery
(
expr
:
Expression
,
inSelect
:
Boolean
)
:
String
=
expr
match
{
case
ClassExpression
(
clsName
)
=>
typeTestExpression
(
clsName
)
case
TraitExpression
(
clsName
)
=>
typeTestExpression
(
clsName
)
private
def
genQuery
(
parent
:
GroovyExpression
,
expr
:
Expression
,
inSelect
:
Boolean
)
:
GroovyExpression
=
expr
match
{
case
ClassExpression
(
clsName
)
=>
typeTestExpression
(
parent
,
clsName
)
case
TraitExpression
(
clsName
)
=>
typeTestExpression
(
parent
,
clsName
)
case
fe
@FieldExpression
(
fieldName
,
fInfo
,
child
)
if
fe
.
dataType
.
getTypeCategory
==
TypeCategory
.
PRIMITIVE
||
fe
.
dataType
.
getTypeCategory
==
TypeCategory
.
ARRAY
=>
{
val
fN
=
"\""
+
gPersistenceBehavior
.
fieldNameInVertex
(
fInfo
.
dataType
,
fInfo
.
attrInfo
)
+
"\""
genPropertyAccessExpr
(
child
,
fInfo
,
fN
,
inSelect
)
}
val
fN
=
gPersistenceBehavior
.
fieldNameInVertex
(
fInfo
.
dataType
,
fInfo
.
attrInfo
)
val
childExpr
=
translateOptChild
(
parent
,
child
,
inSelect
);
return
GremlinExpressionFactory
.
INSTANCE
.
generateFieldExpression
(
childExpr
,
fInfo
,
fN
,
inSelect
);
}
case
fe
@FieldExpression
(
fieldName
,
fInfo
,
child
)
if
fe
.
dataType
.
getTypeCategory
==
TypeCategory
.
CLASS
||
fe
.
dataType
.
getTypeCategory
==
TypeCategory
.
STRUCT
=>
{
val
direction
=
if
(
fInfo
.
isReverse
)
"in"
else
"out"
val
childExpr
=
translateOptChild
(
parent
,
child
,
inSelect
);
val
direction
=
if
(
fInfo
.
isReverse
)
AtlasEdgeDirection
.
IN
else
AtlasEdgeDirection
.
OUT
val
edgeLbl
=
gPersistenceBehavior
.
edgeLabel
(
fInfo
)
val
step
=
s
"""$direction("$edgeLbl")"""
generateAndPrependExpr
(
child
,
inSelect
,
s
"""$step"""
)
}
return
GremlinExpressionFactory
.
INSTANCE
.
generateAdjacentVerticesExpression
(
childExpr
,
direction
,
edgeLbl
)
}
case
fe
@FieldExpression
(
fieldName
,
fInfo
,
child
)
if
fInfo
.
traitName
!=
null
=>
{
val
childExpr
=
translateOptChild
(
parent
,
child
,
inSelect
);
val
direction
=
gPersistenceBehavior
.
instanceToTraitEdgeDirection
val
edgeLbl
=
gPersistenceBehavior
.
edgeLabel
(
fInfo
)
val
step
=
s
"""$direction("$edgeLbl")"""
generateAndPrependExpr
(
child
,
inSelect
,
s
"""$step"""
)
return
GremlinExpressionFactory
.
INSTANCE
.
generateAdjacentVerticesExpression
(
childExpr
,
direction
,
edgeLbl
)
}
case
c
@ComparisonExpression
(
symb
,
f
@FieldExpression
(
fieldName
,
fInfo
,
ch
),
l
)
=>
{
return
genHasPredicate
(
ch
,
fInfo
,
fieldName
,
inSelect
,
c
,
l
)
val
qualifiedPropertyName
=
s
"${gPersistenceBehavior.fieldNameInVertex(fInfo.dataType, fInfo.attrInfo)}"
val
childExpr
=
translateOptChild
(
parent
,
ch
,
inSelect
)
val
persistentExprValue
:
GroovyExpression
=
if
(
l
.
isInstanceOf
[
Literal
[
_
]])
{
translateLiteralValue
(
fInfo
.
attrInfo
.
dataType
,
l
.
asInstanceOf
[
Literal
[
_
]]);
}
else
{
genQuery
(
null
,
l
,
inSelect
);
}
return
GremlinExpressionFactory
.
INSTANCE
.
generateHasExpression
(
gPersistenceBehavior
,
childExpr
,
qualifiedPropertyName
,
c
.
symbol
,
persistentExprValue
,
fInfo
);
}
case
fil
@FilterExpression
(
child
,
condExpr
)
=>
{
s
"${genQuery(child, inSelect)}.${genQuery(condExpr, inSelect)}"
val
newParent
=
genQuery
(
parent
,
child
,
inSelect
);
return
genQuery
(
newParent
,
condExpr
,
inSelect
);
}
case
l
@LogicalExpression
(
symb
,
children
)
=>
{
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
THREE
)
{
if
(
children
.
length
==
1
)
{
//gremlin 3 treats one element expressions as 'false'. Avoid
//creating a boolean expression in this case. Inline the expression
//note: we can't simply omit it, since it will cause us to traverse the edge!
//use 'where' instead
var
child
:
Expression
=
children
.
head
;
//if child is a back expression, that expression becomes an argument to where
return
s
"""where(${genQuery(child, inSelect)})"""
;
}
else
{
// Gremlin 3 does not support _() syntax
//
return
s
"""$symb${children.map( genQuery(_, inSelect)).mkString("(", ",", ")")}"""
}
}
else
{
s
"""$symb${children.map("_()." + genQuery(_, inSelect)).mkString("(", ",", ")")}"""
}
val
translatedChildren
:
java.util.List
[
GroovyExpression
]
=
translateList
(
children
,
true
,
inSelect
);
return
GremlinExpressionFactory
.
INSTANCE
.
generateLogicalExpression
(
parent
,
symb
,
translatedChildren
);
}
case
sel
@SelectExpression
(
child
,
selList
)
=>
{
val
m
=
groupSelectExpressionsBySrc
(
sel
)
var
srcNamesList
:
List
[
String
]
=
List
()
var
srcExprsList
:
List
[
List
[
String
]]
=
List
()
var
srcNamesList
:
java.util.List
[
LiteralExpression
]
=
new
Array
List
()
var
srcExprsList
:
List
[
java.util.List
[
GroovyExpression
]]
=
List
()
val
it
=
m
.
iterator
while
(
it
.
hasNext
)
{
val
(
src
,
selExprs
)
=
it
.
next
srcNamesList
=
srcNamesList
:+
s
""""$src""""
srcExprsList
=
srcExprsList
:+
selExprs
.
map
{
selExpr
=>
genQuery
(
selExpr
,
true
)
}
srcNamesList
.
add
(
new
LiteralExpression
(
src
));
val
translatedSelExprs
:
java.util.List
[
GroovyExpression
]
=
translateList
(
selExprs
,
false
,
true
);
srcExprsList
=
srcExprsList
:+
translatedSelExprs
}
val
srcExprsStringList
=
srcExprsList
.
map
{
_
.
mkString
(
"["
,
","
,
"]"
)
val
srcExprsStringList
:
java.util.List
[
GroovyExpression
]
=
new
ArrayList
();
srcExprsList
.
foreach
{
it
=>
srcExprsStringList
.
add
(
new
ListExpression
(
it
));
}
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
val
srcNamesString
=
srcNamesList
.
mkString
(
"["
,
","
,
"]"
)
val
srcExprsString
=
srcExprsStringList
.
foldLeft
(
""
)(
_
+
"{"
+
_
+
"}"
)
s
"${genQuery(child, inSelect)}.select($srcNamesString)$srcExprsString"
}
else
{
//gremlin 3
val
srcNamesString
=
srcNamesList
.
mkString
(
""
,
","
,
""
)
val
srcExprsString
=
srcExprsStringList
.
foldLeft
(
""
)(
_
+
".by({"
+
_
+
"} as Function)"
)
s
"${genQuery(child, inSelect)}.select($srcNamesString)$srcExprsString"
}
val
childExpr
=
genQuery
(
parent
,
child
,
inSelect
)
return
GremlinExpressionFactory
.
INSTANCE
.
generateSelectExpression
(
childExpr
,
srcNamesList
,
srcExprsStringList
);
}
case
loop
@LoopExpression
(
input
,
loopExpr
,
t
)
=>
{
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
val
inputQry
=
genQuery
(
input
,
inSelect
)
val
loopingPathGExpr
=
genQuery
(
loopExpr
,
inSelect
)
val
loopGExpr
=
s
"""loop("${input.asInstanceOf[AliasExpression].alias}")"""
val
untilCriteria
=
if
(
t
.
isDefined
)
s
"{it.loops < ${t.get.value}}"
else
"{it.path.contains(it.object)?false:true}"
val
loopObjectGExpr
=
gPersistenceBehavior
.
loopObjectExpression
(
input
.
dataType
)
val
enablePathExpr
=
s
".enablePath()"
s
"""${inputQry}.${loopingPathGExpr}.${loopGExpr}${untilCriteria}${loopObjectGExpr}${enablePathExpr}"""
val
times
:
Integer
=
if
(
t
.
isDefined
)
{
t
.
get
.
rawValue
.
asInstanceOf
[
Integer
]
}
else
{
//gremlin 3 - TODO - add support for circular lineage
val
inputQry
=
genQuery
(
input
,
inSelect
)
val
repeatExpr
=
s
"""repeat(__.${genQuery(loopExpr, inSelect)})"""
val
optTimesExpr
=
if
(
t
.
isDefined
)
s
".times(${t.get.value})"
else
""
val
emitExpr
=
s
""".emit(${gPersistenceBehavior.loopObjectExpression(input.dataType)})"""
s
"""${inputQry}.${repeatExpr}${optTimesExpr}${emitExpr}"""
null
.
asInstanceOf
[
Integer
]
}
val
alias
=
input
.
asInstanceOf
[
AliasExpression
].
alias
;
val
inputQry
=
genQuery
(
parent
,
input
,
inSelect
)
val
translatedLoopExpr
=
genQuery
(
GremlinExpressionFactory
.
INSTANCE
.
getLoopExpressionParent
(
inputQry
),
loopExpr
,
inSelect
);
return
GremlinExpressionFactory
.
INSTANCE
.
generateLoopExpression
(
inputQry
,
gPersistenceBehavior
,
input
.
dataType
,
translatedLoopExpr
,
alias
,
times
);
}
case
BackReference
(
alias
,
_
,
_
)
=>
{
if
(
inSelect
)
{
gPersistenceBehavior
.
fieldPrefixInSelect
()
}
else
{
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
s
"""back("$alias")"""
}
else
{
s
"""select("$alias")"""
}
}
return
GremlinExpressionFactory
.
INSTANCE
.
generateBackReferenceExpression
(
parent
,
inSelect
,
alias
);
}
case
AliasExpression
(
child
,
alias
)
=>
{
var
childExpr
=
genQuery
(
parent
,
child
,
inSelect
);
return
GremlinExpressionFactory
.
INSTANCE
.
generateAliasExpression
(
childExpr
,
alias
);
}
case
isTraitLeafExpression
(
traitName
,
Some
(
clsExp
))
=>
{
val
label
=
gPersistenceBehavior
.
traitLabel
(
clsExp
.
dataType
,
traitName
);
return
GremlinExpressionFactory
.
INSTANCE
.
generateAdjacentVerticesExpression
(
parent
,
AtlasEdgeDirection
.
OUT
,
label
);
}
case
isTraitUnaryExpression
(
traitName
,
child
)
=>
{
val
label
=
gPersistenceBehavior
.
traitLabel
(
child
.
dataType
,
traitName
);
return
GremlinExpressionFactory
.
INSTANCE
.
generateAdjacentVerticesExpression
(
parent
,
AtlasEdgeDirection
.
OUT
,
label
);
}
case
AliasExpression
(
child
,
alias
)
=>
s
"""${genQuery(child, inSelect)}.as("$alias")"""
case
isTraitLeafExpression
(
traitName
,
Some
(
clsExp
))
=>
s
"""out("${gPersistenceBehavior.traitLabel(clsExp.dataType, traitName)}")"""
case
isTraitUnaryExpression
(
traitName
,
child
)
=>
s
"""out("${gPersistenceBehavior.traitLabel(child.dataType, traitName)}")"""
case
hasFieldLeafExpression
(
fieldName
,
clsExp
)
=>
clsExp
match
{
case
None
=>
s
"""has("$fieldName")"""
case
None
=>
GremlinExpressionFactory
.
INSTANCE
.
generateUnaryHasExpression
(
parent
,
fieldName
)
case
Some
(
x
)
=>
{
val
fi
=
TypeUtils
.
resolveReference
(
clsExp
.
get
.
dataType
,
fieldName
);
if
(!
fi
.
isDefined
)
{
s
"""has("$fieldName")"""
return
GremlinExpressionFactory
.
INSTANCE
.
generateUnaryHasExpression
(
parent
,
fieldName
);
}
else
{
s
"""has("${gPersistenceBehavior.fieldNameInVertex(fi.get.dataType, fi.get.attrInfo)}")"""
val
fName
=
gPersistenceBehavior
.
fieldNameInVertex
(
fi
.
get
.
dataType
,
fi
.
get
.
attrInfo
)
return
GremlinExpressionFactory
.
INSTANCE
.
generateUnaryHasExpression
(
parent
,
fName
);
}
}
}
case
hasFieldUnaryExpression
(
fieldName
,
child
)
=>
s
"""${genQuery(child, inSelect)}.has("$fieldName")"""
case
ArithmeticExpression
(
symb
,
left
,
right
)
=>
s
"${genQuery(left, inSelect)} $symb ${genQuery(right, inSelect)}"
case
l
:
Literal
[
_
]
=>
l
.
toString
case
list
:
ListLiteral
[
_
]
=>
list
.
toString
val
childExpr
=
genQuery
(
parent
,
child
,
inSelect
);
return
GremlinExpressionFactory
.
INSTANCE
.
generateUnaryHasExpression
(
childExpr
,
fieldName
);
case
ArithmeticExpression
(
symb
,
left
,
right
)
=>
{
val
leftExpr
=
genQuery
(
parent
,
left
,
inSelect
);
val
rightExpr
=
genQuery
(
parent
,
right
,
inSelect
);
return
GremlinExpressionFactory
.
INSTANCE
.
generateArithmeticExpression
(
leftExpr
,
symb
,
rightExpr
);
}
case
l
:
Literal
[
_
]
=>
{
if
(
parent
!=
null
)
{
return
new
org
.
apache
.
atlas
.
groovy
.
FieldExpression
(
parent
,
cleanStringLiteral
(
l
));
}
return
translateLiteralValue
(
l
.
dataType
,
l
);
}
case
list
:
ListLiteral
[
_
]
=>
{
val
values
:
java.util.List
[
GroovyExpression
]
=
translateList
(
list
.
rawValue
,
false
,
inSelect
);
return
new
ListExpression
(
values
);
}
case
in
@TraitInstanceExpression
(
child
)
=>
{
val
direction
=
gPersistenceBehavior
.
traitToInstanceEdgeDirection
s
"${genQuery(child, inSelect)}.$direction()"
val
childExpr
=
genQuery
(
parent
,
child
,
inSelect
);
val
direction
=
gPersistenceBehavior
.
traitToInstanceEdgeDirection
;
return
GremlinExpressionFactory
.
INSTANCE
.
generateAdjacentVerticesExpression
(
childExpr
,
direction
);
}
case
in
@InstanceExpression
(
child
)
=>
{
s
"${genQuery(child, inSelect)}"
return
genQuery
(
parent
,
child
,
inSelect
);
}
case
pe
@PathExpression
(
child
)
=>
{
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
s
"${genQuery(child, inSelect)}.path"
}
else
{
s
"${genQuery(child, inSelect)}.path()"
}
val
childExpr
=
genQuery
(
parent
,
child
,
inSelect
)
return
GremlinExpressionFactory
.
INSTANCE
.
generatePathExpression
(
childExpr
);
}
case
order
@OrderExpression
(
child
,
odr
,
asc
)
=>
{
var
orderby
=
""
var
orderExpression
=
odr
if
(
odr
.
isInstanceOf
[
BackReference
])
{
orderExpression
=
odr
.
asInstanceOf
[
BackReference
].
reference
if
(
odr
.
isInstanceOf
[
BackReference
])
{
orderExpression
=
odr
.
asInstanceOf
[
BackReference
].
reference
}
else
if
(
odr
.
isInstanceOf
[
AliasExpression
])
{
else
if
(
odr
.
isInstanceOf
[
AliasExpression
])
{
orderExpression
=
odr
.
asInstanceOf
[
AliasExpression
].
child
}
val
orderbyProperty
=
genQuery
(
orderExpression
,
false
)
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
val
bProperty
=
s
"it.b.$orderbyProperty"
val
aProperty
=
s
"it.a.$orderbyProperty"
val
aCondition
=
s
"($aProperty != null ? $aProperty.toLowerCase(): $aProperty)"
val
bCondition
=
s
"($bProperty != null ? $bProperty.toLowerCase(): $bProperty)"
orderby
=
asc
match
{
//builds a closure comparison function based on provided order by clause in DSL. This will be used to sort the results by gremlin order pipe.
//Ordering is case insensitive.
case
false
=>
s
"order{$bCondition <=> $aCondition}"
//descending
case
_
=>
s
"order{$aCondition <=> $bCondition}"
}
}
else
{
val
orderbyProperty
=
genQuery
(
orderExpression
,
true
);
val
aPropertyExpr
=
gremlin3ToLowerCase
(
"a"
);
val
bPropertyExpr
=
gremlin3ToLowerCase
(
"b"
);
orderby
=
asc
match
{
//builds a closure comparison function based on provided order by clause in DSL. This will be used to sort the results by gremlin order pipe.
//Ordering is case insensitive.
case
false
=>
s
"""order().by({$orderbyProperty'}, { a,b -> $bPropertyExpr <=> $aPropertyExpr })"""
case
_
=>
s
"""order().by({$orderbyProperty},{ a,b -> $aPropertyExpr <=> $bPropertyExpr })"""
}
val
childExpr
=
genQuery
(
parent
,
child
,
inSelect
);
var
orderByParents
:
java.util.List
[
GroovyExpression
]
=
GremlinExpressionFactory
.
INSTANCE
.
getOrderFieldParents
();
val
translatedParents
:
java.util.List
[
GroovyExpression
]
=
new
ArrayList
[
GroovyExpression
]();
var
translatedOrderParents
=
orderByParents
.
foreach
{
it
=>
translatedParents
.
add
(
genQuery
(
it
,
orderExpression
,
false
));
}
s
"""${genQuery(child, inSelect)}.$orderby"""
return
GremlinExpressionFactory
.
INSTANCE
.
generateOrderByExpression
(
childExpr
,
translatedParents
,
asc
);
}
case
limitOffset
@LimitExpression
(
child
,
limit
,
offset
)
=>
{
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
val
totalResultRows
=
limit
.
value
+
offset
.
value
s
"""${genQuery(child, inSelect)} [$offset..<$totalResultRows]"""
}
else
{
val
totalResultRows
=
limit
.
value
+
offset
.
value
s
"""${genQuery(child, inSelect)}.range($offset,$totalResultRows)"""
}
val
childExpr
=
genQuery
(
parent
,
child
,
inSelect
);
val
totalResultRows
=
limit
.
value
+
offset
.
value
;
return
GremlinExpressionFactory
.
INSTANCE
.
generateLimitExpression
(
childExpr
,
offset
.
value
,
totalResultRows
);
}
case
x
=>
throw
new
GremlinTranslationException
(
x
,
"expression not yet supported"
)
}
def
gremlin3ToLowerCase
(
varName
:
String
)
:
String
=
{
s
"""($varName != null ? $varName.toString().toLowerCase() : null)"""
}
def
genPropertyAccessExpr
(
e
:
Option
[
Expression
],
fInfo
:
FieldInfo
,
quotedPropertyName
:
String
,
inSelect
:
Boolean
)
:
String
=
{
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
generateAndPrependExpr
(
e
,
inSelect
,
s
"""$quotedPropertyName"""
)
}
else
{
val
attrInfo
:
AttributeInfo
=
fInfo
.
attrInfo
;
val
attrType
:
IDataType
[
_
]
=
attrInfo
.
dataType
;
if
(
inSelect
)
{
val
expr
=
generateAndPrependExpr
(
e
,
inSelect
,
s
"""property($quotedPropertyName).orElse(null)"""
);
return
gPersistenceBehavior
.
generatePersisentToLogicalConversionExpression
(
expr
,
attrType
);
}
else
{
val
unmapped
=
s
"""values($quotedPropertyName)"""
val
expr
=
if
(
gPersistenceBehavior
.
isPropertyValueConversionNeeded
(
attrType
))
{
val
conversionFunction
=
gPersistenceBehavior
.
generatePersisentToLogicalConversionExpression
(
s
"""it.get()"""
,
attrType
);
s
"""$unmapped.map{ $conversionFunction }"""
}
else
{
unmapped
}
generateAndPrependExpr
(
e
,
inSelect
,
expr
)
}
def
translateList
(
exprs
:
List
[
Expressions.Expression
],
isAnonymousTraveral
:
Boolean
,
inSelect
:
Boolean
)
:
java.util.List
[
GroovyExpression
]
=
{
var
parent
=
if
(
isAnonymousTraveral
)
{
GremlinExpressionFactory
.
INSTANCE
.
getAnonymousTraversalExpression
()
}
else
{
null
}
var
result
:
java.util.List
[
GroovyExpression
]
=
new
java
.
util
.
ArrayList
(
exprs
.
size
);
exprs
.
foreach
{
it
=>
result
.
add
(
genQuery
(
parent
,
it
,
inSelect
));
}
return
result
;
}
def
generateAndPrependExpr
(
e1
:
Option
[
Expression
],
inSelect
:
Boolean
,
e2
:
String
)
:
String
=
e1
match
{
def
translateOptChild
(
parent
:
GroovyExpression
,
child
:
Option
[
Expressions.Expression
]
,
inSelect
:
Boolean
)
:
GroovyExpression
=
child
match
{
case
Some
(
x
)
=>
s
"""${genQuery(x, inSelect)}.$e2"""
case
None
=>
e2
case
Some
(
x
)
=>
genQuery
(
parent
,
x
,
inSelect
)
case
None
=>
parent
}
def
genHasPredicate
(
e
:
Option
[
Expression
],
fInfo
:
FieldInfo
,
fieldName
:
String
,
inSelect
:
Boolean
,
c
:
ComparisonExpression
,
expr
:
Expression
)
:
String
=
{
def
translateLiteralValue
(
dataType
:
IDataType
[
_
],
l
:
Literal
[
_
])
:
GroovyExpression
=
{
val
qualifiedPropertyName
=
s
"${gPersistenceBehavior.fieldNameInVertex(fInfo.dataType, fInfo.attrInfo)}"
val
persistentExprValue
=
translateValueToPersistentForm
(
fInfo
,
expr
);
if
(
gPersistenceBehavior
.
getSupportedGremlinVersion
()
==
GremlinVersion
.
TWO
)
{
return
generateAndPrependExpr
(
e
,
inSelect
,
s
"""has("${qualifiedPropertyName}", ${gPersistenceBehavior.gremlinCompOp(c)}, $persistentExprValue)"""
);
if
(
dataType
==
DataTypes
.
DATE_TYPE
)
{
try
{
//Accepts both date, datetime formats
val
dateStr
=
cleanStringLiteral
(
l
)
val
dateVal
=
ISODateTimeFormat
.
dateOptionalTimeParser
().
parseDateTime
(
dateStr
).
getMillis
return
new
LiteralExpression
(
dateVal
)
}
catch
{
case
pe
:
java.text.ParseException
=>
throw
new
GremlinTranslationException
(
l
,
"Date format "
+
l
+
" not supported. Should be of the format "
+
TypeSystem
.
getInstance
().
getDateFormat
.
toPattern
);
}
}
else
if
(
dataType
==
DataTypes
.
BYTE_TYPE
)
{
//cast needed, otherwise get class cast exception when trying to compare, since the
//persist value is assumed to be an Integer
return
new
CastExpression
(
new
LiteralExpression
(
Byte
.
valueOf
(
s
"""${l}"""
),
true
),
"byte"
);
}
else
if
(
dataType
==
DataTypes
.
INT_TYPE
)
{
return
new
LiteralExpression
(
Integer
.
valueOf
(
s
"""${l}"""
));
}
else
if
(
dataType
==
DataTypes
.
BOOLEAN_TYPE
)
{
return
new
LiteralExpression
(
Boolean
.
valueOf
(
s
"""${l}"""
));
}
else
if
(
dataType
==
DataTypes
.
SHORT_TYPE
)
{
return
new
CastExpression
(
new
LiteralExpression
(
Short
.
valueOf
(
s
"""${l}"""
),
true
),
"short"
);
}
else
if
(
dataType
==
DataTypes
.
LONG_TYPE
)
{
return
new
LiteralExpression
(
Long
.
valueOf
(
s
"""${l}"""
),
true
);
}
else
if
(
dataType
==
DataTypes
.
FLOAT_TYPE
)
{
return
new
LiteralExpression
(
Float
.
valueOf
(
s
"""${l}"""
),
true
);
}
else
if
(
dataType
==
DataTypes
.
DOUBLE_TYPE
)
{
return
new
LiteralExpression
(
Double
.
valueOf
(
s
"""${l}"""
),
true
);
}
else
if
(
dataType
==
DataTypes
.
STRING_TYPE
)
{
return
new
LiteralExpression
(
cleanStringLiteral
(
l
));
}
else
{
val
attrInfo
:
AttributeInfo
=
fInfo
.
attrInfo
;
val
attrType
:
IDataType
[
_
]
=
attrInfo
.
dataType
;
if
(
gPersistenceBehavior
.
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
val
vertexExpr
=
"((Vertex)it.get())"
;
val
conversionExpr
=
gPersistenceBehavior
.
generatePersisentToLogicalConversionExpression
(
s
"""$vertexExpr.value("$qualifiedPropertyName")"""
,
attrType
);
return
generateAndPrependExpr
(
e
,
inSelect
,
s
"""filter{$vertexExpr.property("$qualifiedPropertyName").isPresent() && $conversionExpr ${gPersistenceBehavior.gremlinPrimitiveOp(c)} $persistentExprValue}"""
);
}
else
{
return
generateAndPrependExpr
(
e
,
inSelect
,
s
"""has("${qualifiedPropertyName}", ${gPersistenceBehavior.gremlinCompOp(c)}($persistentExprValue))"""
);
}
}
return
new
LiteralExpression
(
l
.
rawValue
);
}
}
def
translateValueToPersistentForm
(
fInfo
:
FieldInfo
,
l
:
Expression
)
:
Any
=
{
val
dataType
=
fInfo
.
attrInfo
.
dataType
;
val
QUOTE
=
"\""
;
if
(
dataType
==
DataTypes
.
DATE_TYPE
)
{
try
{
//Accepts both date, datetime formats
val
dateStr
=
l
.
toString
.
stripPrefix
(
QUOTE
).
stripSuffix
(
QUOTE
)
val
dateVal
=
ISODateTimeFormat
.
dateOptionalTimeParser
().
parseDateTime
(
dateStr
).
getMillis
return
dateVal
}
catch
{
case
pe
:
java.text.ParseException
=>
throw
new
GremlinTranslationException
(
l
,
"Date format "
+
l
+
" not supported. Should be of the format "
+
TypeSystem
.
getInstance
().
getDateFormat
.
toPattern
);
}
}
else
if
(
dataType
==
DataTypes
.
BYTE_TYPE
)
{
//cast needed, otherwise get class cast exception when trying to compare, since the
//persist value is assumed to be an Integer
return
s
"""(byte)$l"""
}
else
if
(
dataType
==
DataTypes
.
SHORT_TYPE
)
{
return
s
"""(short)$l"""
}
else
if
(
dataType
==
DataTypes
.
LONG_TYPE
)
{
return
s
"""${l}L"""
}
else
if
(
dataType
==
DataTypes
.
FLOAT_TYPE
)
{
return
s
"""${l}f"""
}
else
if
(
dataType
==
DataTypes
.
DOUBLE_TYPE
)
{
return
s
"""${l}d"""
}
else
if
(
dataType
==
DataTypes
.
STRING_TYPE
)
{
return
string
(
escape
(
l
.
toString
.
stripPrefix
(
QUOTE
).
stripSuffix
(
QUOTE
)));
}
else
{
return
l
}
}
def
genFullQuery
(
expr
:
Expression
,
hasSelect
:
Boolean
)
:
String
=
{
var
q
=
genQuery
(
expr
,
false
)
var
q
:
GroovyExpression
=
new
FunctionCallExpression
(
new
IdentifierExpression
(
"g"
),
"V"
);
val
debug
:
Boolean
=
false
if
(
gPersistenceBehavior
.
addGraphVertexPrefix
(
preStatements
))
{
q
=
s
"g.V()${gPersistenceBehavior.initialQueryCondition}.$q"
q
=
gPersistenceBehavior
.
addInitialQueryCondition
(
q
);
}
q
=
s
"$q.toList()${gPersistenceBehavior.getGraph().getOutputTransformationPredicate(hasSelect, expr.isInstanceOf[PathExpression])}"
q
=
genQuery
(
q
,
expr
,
false
)
q
=
new
FunctionCallExpression
(
q
,
"toList"
);
q
=
gPersistenceBehavior
.
getGraph
().
addOutputTransformationPredicate
(
q
,
hasSelect
,
expr
.
isInstanceOf
[
PathExpression
]);
var
overallExpression
=
new
CodeBlockExpression
();
overallExpression
.
addStatements
(
preStatements
);
overallExpression
.
addStatement
(
q
)
overallExpression
.
addStatements
(
postStatements
);
var
qryStr
=
generateGremlin
(
overallExpression
);
if
(
debug
)
{
println
(
" query "
+
q
)
println
(
" query "
+
q
ryStr
)
}
q
=
(
preStatements
++
Seq
(
q
)
++
postStatements
).
mkString
(
""
,
";"
,
""
)
/*
* the L:{} represents a groovy code block; the label is needed
* to distinguish it from a groovy closure.
*/
s
"L:{$q}"
qryStr
;
}
def
generateGremlin
(
expr
:
GroovyExpression
)
:
String
=
{
val
ctx
:
GroovyGenerationContext
=
new
GroovyGenerationContext
();
ctx
.
setParametersAllowed
(
false
);
expr
.
generateGroovy
(
ctx
);
return
ctx
.
getQuery
;
}
def
translate
()
:
GremlinQuery
=
{
var
e1
=
expr
.
transformUp
(
wrapAndRule
)
...
...
@@ -570,9 +537,9 @@ class GremlinTranslator(expr: Expression,
e1
=
e1
.
transformUp
(
addAliasToLoopInput
())
e1
=
e1
.
transformUp
(
instanceClauseToTop
(
e1
))
e1
=
e1
.
transformUp
(
traitClauseWithInstanceForTop
(
e1
))
//Following code extracts the select expressions from expression tree.
val
se
=
SelectExpressionHelper
.
extractSelectExpression
(
e1
)
if
(
se
.
isDefined
)
{
val
rMap
=
buildResultMapping
(
se
.
get
)
...
...
This diff is collapsed.
Click to expand it.
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