Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Georg Fette
CDW_QueryMapper
Commits
dcc137af
Commit
dcc137af
authored
Mar 08, 2019
by
Georg Fette
Browse files
added aggregation operators avg and count with test cases
parent
3300400e
Changes
13
Hide whitespace changes
Inline
Side-by-side
QueryMapper/src/main/java/de/uniwue/query/CQL/CQL_2_Graph_Mapper.java
View file @
dcc137af
...
...
@@ -120,10 +120,10 @@ public class CQL_2_Graph_Mapper {
return
prettyTree
;
}
private
void
addOp
(
OperatorType
aType
)
{
private
void
addOp
(
OperatorType
aType
)
{
currentOp
=
new
QueryOperator
(
currentOp
,
aType
);
}
private
cqlParser
.
QueryExpressionContext
parseWithAntlr
(
String
aQueryString
)
{
ANTLRInputStream
stream
=
new
ANTLRInputStream
(
aQueryString
);
cqlLexer
lexer
=
new
cqlLexer
(
stream
);
...
...
@@ -141,9 +141,20 @@ public class CQL_2_Graph_Mapper {
QueryExpressionContext
qe
=
parseWithAntlr
(
aQueryString
);
parseQueryExpression
(
qe
);
addLeafsToRootClause
();
addDefaultReturnIfNecessary
();
return
query
;
}
private
void
addDefaultReturnIfNecessary
()
{
if
(
query
.
getReturnedExpressions
().
size
()
==
0
)
{
if
(
query
.
rootConcepts
.
size
()
>
0
)
{
query
.
rootConcepts
.
get
(
0
).
includeInResult
=
true
;
}
else
{
query
.
rootClause
.
getParameters
().
get
(
0
).
includeInResult
=
true
;
}
}
}
private
void
parseQueryExpression
(
QueryExpressionContext
qe
)
{
String
prettyPrint
=
prettyPrint
(
qe
);
QueryContext
queryContext
=
qe
.
query
();
...
...
@@ -253,7 +264,7 @@ public class CQL_2_Graph_Mapper {
private
void
addLeafsToRootClause
()
{
// add leafs that are not yet part of any operator to the root and
for
(
QueryConcept
aConc
:
query
.
ge
tConcepts
Recursive
()
)
{
for
(
QueryConcept
aConc
:
query
.
roo
tConcepts
)
{
for
(
QueryConcept
aLeaf
:
aConc
.
getLeafsRecursive
())
{
if
(
aLeaf
.
parentOps
.
size
()
==
0
)
{
query
.
rootClause
.
addParameter
(
aLeaf
);
...
...
@@ -598,6 +609,8 @@ public class CQL_2_Graph_Mapper {
opType
=
OperatorType
.
LAST
;
}
else
if
(
text
.
equals
(
"Count"
))
{
opType
=
OperatorType
.
COUNT
;
}
else
if
(
text
.
equals
(
"Avg"
))
{
opType
=
OperatorType
.
AVG
;
}
else
{
throw
new
RuntimeException
(
"unexpected"
);
}
...
...
@@ -608,6 +621,9 @@ public class CQL_2_Graph_Mapper {
// TODO: the contained parameter might as well be an arbitrary expression
setCurrentPath
(
new
GraphPath
(
newOp
.
getParameters
().
get
(
0
).
asConcept
()));
}
if
(
opType
==
OperatorType
.
COUNT
)
{
// here should something happen that determines the scope of the aggregation op
}
}
else
{
throw
new
RuntimeException
(
"unexpected"
);
}
...
...
QueryMapper/src/main/java/de/uniwue/query/Expression.java
View file @
dcc137af
package
de.uniwue.query
;
import
java.util.
Lis
t
;
import
java.util.
Se
t
;
public
abstract
class
Expression
{
...
...
@@ -28,7 +28,7 @@ public abstract class Expression {
return
(
QueryOperator
)
this
;
}
public
abstract
void
getReturnedExpressions
(
Lis
t
<
Expression
>
results
);
public
abstract
void
getReturnedExpressions
(
Se
t
<
Expression
>
results
);
public
boolean
includeInResult
;
...
...
QueryMapper/src/main/java/de/uniwue/query/GraphQuery.java
View file @
dcc137af
package
de.uniwue.query
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
public
class
GraphQuery
{
...
...
@@ -31,8 +33,8 @@ public class GraphQuery {
return
result
;
}
public
Lis
t
<
Expression
>
getReturnedExpressions
()
{
Lis
t
<
Expression
>
returns
=
new
ArrayLis
t
<
Expression
>();
public
Se
t
<
Expression
>
getReturnedExpressions
()
{
Se
t
<
Expression
>
returns
=
new
HashSe
t
<
Expression
>();
for
(
QueryConcept
aConc
:
getConceptsRecursive
())
{
aConc
.
getReturnedExpressions
(
returns
);
}
...
...
QueryMapper/src/main/java/de/uniwue/query/OperatorType.java
View file @
dcc137af
...
...
@@ -40,6 +40,7 @@ public enum OperatorType {
// aggregation
COUNT
,
AVG
,
// arithmetics
POWER
,
...
...
QueryMapper/src/main/java/de/uniwue/query/Primitive.java
View file @
dcc137af
package
de.uniwue.query
;
import
java.util.
Lis
t
;
import
java.util.
Se
t
;
public
class
Primitive
extends
Expression
{
...
...
@@ -36,7 +36,7 @@ public class Primitive extends Expression {
return
result
;
}
public
void
getReturnedExpressions
(
Lis
t
<
Expression
>
results
)
{
public
void
getReturnedExpressions
(
Se
t
<
Expression
>
results
)
{
if
(
includeInResult
)
{
results
.
add
(
this
);
}
...
...
QueryMapper/src/main/java/de/uniwue/query/QueryConcept.java
View file @
dcc137af
...
...
@@ -3,6 +3,7 @@ package de.uniwue.query;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Set
;
import
de.uniwue.misc.util.StringUtilsUniWue
;
...
...
@@ -140,7 +141,7 @@ public class QueryConcept extends Expression {
return
result
;
}
public
void
getReturnedExpressions
(
Lis
t
<
Expression
>
results
)
{
public
void
getReturnedExpressions
(
Se
t
<
Expression
>
results
)
{
if
(
includeInResult
)
{
results
.
add
(
this
);
}
...
...
QueryMapper/src/main/java/de/uniwue/query/QueryOperator.java
View file @
dcc137af
...
...
@@ -2,6 +2,7 @@ package de.uniwue.query;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Set
;
import
de.uniwue.misc.util.StringUtilsUniWue
;
import
de.uniwue.query.Primitive.PrimitiveDataType
;
...
...
@@ -179,7 +180,7 @@ public class QueryOperator extends Expression {
return
result
;
}
public
void
getReturnedExpressions
(
Lis
t
<
Expression
>
results
)
{
public
void
getReturnedExpressions
(
Se
t
<
Expression
>
results
)
{
if
(
includeInResult
)
{
results
.
add
(
this
);
}
...
...
QueryMapper/src/main/java/de/uniwue/query/cypher/CypherOperatorMapper.java
View file @
dcc137af
...
...
@@ -21,6 +21,7 @@ public class CypherOperatorMapper {
aMap
.
addOp
(
"OR"
,
OperatorType
.
OR
);
aMap
.
addOp
(
"count"
,
OperatorType
.
COUNT
);
aMap
.
addOp
(
"avg"
,
OperatorType
.
AVG
);
aMap
.
addOp
(
"First"
,
OperatorType
.
FIRST
);
aMap
.
addOp
(
"Last"
,
OperatorType
.
LAST
);
aMap
.
addOp
(
"In"
,
OperatorType
.
IN
);
...
...
QueryMapper/src/main/java/de/uniwue/query/cypher/Graph_2_Cypher_Mapper.java
View file @
dcc137af
...
...
@@ -49,11 +49,20 @@ public class Graph_2_Cypher_Mapper extends Graph_2_System_Mapper {
// TODO: fill
@SuppressWarnings
(
"unchecked"
)
private
Set
<
OperatorType
>
infixOp
erator
s
=
new
HashSet
<
OperatorType
>(
private
Set
<
OperatorType
>
infixOps
=
new
HashSet
<
OperatorType
>(
Arrays
.
asList
(
new
OperatorType
[]
{
OperatorType
.
MORE
,
OperatorType
.
LESS
,
OperatorType
.
AND
,
OperatorType
.
EQUALS
,
OperatorType
.
AFTER
,
OperatorType
.
POWER
,
OperatorType
.
ADD
,
OperatorType
.
MULTIPLY
,
OperatorType
.
DIVIDE
,
OperatorType
.
SUBTRACT
}));
@SuppressWarnings
(
"unchecked"
)
private
Set
<
OperatorType
>
aggrOps
=
new
HashSet
<
OperatorType
>(
Arrays
.
asList
(
new
OperatorType
[]
{
OperatorType
.
LAST
,
OperatorType
.
FIRST
,
OperatorType
.
COUNT
}));
@SuppressWarnings
(
"unchecked"
)
private
Set
<
OperatorType
>
compOps
=
new
HashSet
<
OperatorType
>(
Arrays
.
asList
(
new
OperatorType
[]
{
OperatorType
.
EQUALS
,
OperatorType
.
MORE
,
OperatorType
.
MORE_OR_EQUAL
,
OperatorType
.
LESS
,
OperatorType
.
LESS_OR_EQUAL
}));
public
Graph_2_Cypher_Mapper
()
{
super
(
system
);
CypherOperatorMapper
.
initializeOpMappings
(
opMap
);
...
...
@@ -243,7 +252,7 @@ public class Graph_2_Cypher_Mapper extends Graph_2_System_Mapper {
private
String
writeOperator
(
QueryOperator
anOp
)
{
String
result
;
if
(
infixOp
erator
s
.
contains
(
anOp
.
type
))
{
if
(
infixOps
.
contains
(
anOp
.
type
))
{
result
=
writeInfixOperator
(
anOp
);
}
else
if
(
anOp
.
type
==
OperatorType
.
LAST
)
{
result
=
writeLast
(
anOp
);
...
...
@@ -328,7 +337,19 @@ public class Graph_2_Cypher_Mapper extends Graph_2_System_Mapper {
private
String
writeWhere
(
GraphQuery
aQuery
)
{
String
result
=
""
;
boolean
first
=
true
;
boolean
containsComparator
=
false
;
for
(
QueryOperator
aClause
:
aQuery
.
rootClause
.
getOperatorsRecursive
())
{
if
(
compOps
.
contains
(
aClause
.
type
))
{
containsComparator
=
true
;
}
}
if
(!
containsComparator
)
{
return
result
;
}
for
(
QueryOperator
aClause
:
aQuery
.
rootClause
.
getOperators
())
{
if
(
aClause
.
includeInResult
)
{
continue
;
}
if
(
first
)
{
result
=
result
+
" WHERE "
;
first
=
false
;
...
...
@@ -344,7 +365,7 @@ public class Graph_2_Cypher_Mapper extends Graph_2_System_Mapper {
private
String
writeReturn
(
GraphQuery
aQuery
)
{
String
result
=
" RETURN "
;
boolean
first
=
true
;
Lis
t
<
Expression
>
returnedExpressions
=
aQuery
.
getReturnedExpressions
();
Se
t
<
Expression
>
returnedExpressions
=
aQuery
.
getReturnedExpressions
();
for
(
Expression
anExp
:
returnedExpressions
)
{
if
(!
first
)
{
result
+=
", "
;
...
...
@@ -355,8 +376,13 @@ public class Graph_2_Cypher_Mapper extends Graph_2_System_Mapper {
String
alias
=
aliasesConcs
.
get
(
anExp
.
asConcept
());
result
+=
alias
;
}
else
if
(
anExp
.
isOperator
())
{
String
alias
=
aliasesOps
.
get
(
anExp
.
asOperator
());
result
+=
alias
;
QueryOperator
anOp
=
anExp
.
asOperator
();
if
(
aliasesOps
.
containsKey
(
anOp
))
{
String
alias
=
aliasesOps
.
get
(
anOp
);
result
+=
alias
;
}
else
{
result
+=
writeOperator
(
anOp
);
}
}
else
if
(
anExp
.
isPrimitive
())
{
result
+=
anExp
.
asPrimitive
().
toString
();
}
else
{
...
...
@@ -384,7 +410,40 @@ public class Graph_2_Cypher_Mapper extends Graph_2_System_Mapper {
return
result
;
}
private
String
writeLastWithPart
(
GraphQuery
aQuery
,
QueryOperator
anOp
)
{
private
String
writeAggrOpWithPart
(
GraphQuery
aQuery
,
QueryOperator
anOp
)
{
if
(
anOp
.
type
==
OperatorType
.
LAST
)
{
return
writeLastOpWithPart
(
aQuery
,
anOp
);
}
QueryConcept
pathEnd
=
anOp
.
getParameters
().
get
(
0
).
asConcept
();
QueryConcept
currentConc
=
pathEnd
;
String
path
=
""
;
while
(!
aliasesConcs
.
containsKey
(
currentConc
))
{
if
(!
path
.
isEmpty
())
{
path
=
"."
+
path
;
}
path
=
currentConc
.
code
+
path
;
currentConc
=
currentConc
.
parentConcept
;
}
String
alias
=
aliasesConcs
.
get
(
currentConc
);
String
opString
=
opMap
.
graph_2_system_operatorMap
.
get
(
anOp
.
type
);
String
fullPath
=
alias
;
if
(!
path
.
isEmpty
())
{
fullPath
+=
"."
+
path
;
}
String
result
=
opString
+
"("
+
fullPath
+
")"
;
String
opAlias
=
aliasNames
[
aliasIndex
++];
aliasesOps
.
put
(
anOp
,
opAlias
);
result
+=
" AS "
+
opAlias
;
for
(
QueryConcept
aConc
:
aQuery
.
getConceptsRecursive
())
{
if
(
aliasesConcs
.
containsKey
(
aConc
))
{
String
returnAlias
=
aliasesConcs
.
get
(
aConc
);
result
+=
", "
+
returnAlias
;
}
}
return
result
;
}
private
String
writeLastOpWithPart
(
GraphQuery
aQuery
,
QueryOperator
anOp
)
{
// the max-operator may not group by all intermediate concepts which the last operator is
// traversing during its path to the final member that has to serve as the comparison target
List
<
QueryConcept
>
notToAggregateConcets
=
new
ArrayList
<
QueryConcept
>();
...
...
@@ -418,12 +477,12 @@ public class Graph_2_Cypher_Mapper extends Graph_2_System_Mapper {
private
String
writeWith
(
GraphQuery
aQuery
)
{
String
result
=
""
;
for
(
QueryOperator
anOp
:
aQuery
.
rootClause
.
getOperatorsRecursive
())
{
// TODO: change this to an aggregator set check
if
(
anOp
.
type
==
OperatorType
.
LAST
)
{
if
(
aggrOps
.
contains
(
anOp
.
type
)
&&
anOp
.
getParameters
().
size
()
>
1
)
{
// if size > 1 then there is a scope
if
(
result
.
isEmpty
())
{
result
=
" WITH "
;
}
result
+=
write
Last
WithPart
(
aQuery
,
anOp
);
result
+=
write
AggrOp
WithPart
(
aQuery
,
anOp
);
}
}
return
result
;
...
...
QueryMapper/src/test/java/de/uniwue/query/Test_CQL_2_Cypher.java
View file @
dcc137af
...
...
@@ -28,7 +28,7 @@ public class Test_CQL_2_Cypher {
QueryManager
queryManager
=
new
QueryManager
();
initialize
();
for
(
MultiQuery
aMultiQuery
:
queryManager
.
queries
)
{
if
(
aMultiQuery
.
name
.
equals
(
"query_CQL_2_Cypher_
Count
"
))
{
if
(
aMultiQuery
.
name
.
equals
(
"query_CQL_2_Cypher_
Avg
"
))
{
processQuery
(
aMultiQuery
);
}
}
...
...
QueryMapper/src/test/resources/queries/working_CQL_2_Cypher/query_CQL_2_Cypher_Avg.txt
0 → 100644
View file @
dcc137af
*CQL
[Encounter] A return Avg(A.length.value)
*Cypher
MATCH (A:Encounter)-[:LENGTH]->(B:Duration) RETURN avg(B.value)
\ No newline at end of file
QueryMapper/src/test/resources/queries/
notYetW
orkingCQL_2_Cypher/query_CQL_2_Cypher_Count.txt
→
QueryMapper/src/test/resources/queries/
w
orking
_
CQL_2_Cypher/query_CQL_2_Cypher_Count.txt
View file @
dcc137af
*CQL
[Patient] A return Count(A)
*CQLx
[Patient] A where Count(A.name.given) > 1 return A
*Cypher
MATCH (A:Patient) RETURN count(A)
QueryMapper/src/test/resources/queries/working_CQL_2_Cypher/query_CQL_2_Cypher_Count_with_Const.txt
0 → 100644
View file @
dcc137af
*CQL
[Patient] A where A.name.family = 'smith' return Count(A)
*Cypher
MATCH (A:Patient)-[:NAME]->(B:HumanName) WHERE B.family = 'smith' RETURN count(A)
Write
Preview
Supports
Markdown
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