Commit 947931a8 authored by Georg Fette's avatar Georg Fette
Browse files

added more CQL-tests

parent d72d039d
......@@ -19,6 +19,8 @@ public class CQLOperatorMapper {
aMap.addOp("and", OperatorType.AND);
aMap.addOp("or", OperatorType.OR);
aMap.addOp("alltrue", OperatorType.ALLTRUE);
aMap.addOp("anytrue", OperatorType.ANYTRUE);
aMap.addOp("First", OperatorType.FIRST);
aMap.addOp("Last", OperatorType.LAST);
......@@ -42,6 +44,16 @@ public class CQLOperatorMapper {
aMap.addOp(">", OperatorType.MORE);
aMap.addOp(">=", OperatorType.MORE_OR_EQUAL);
aMap.addOp("Avg", OperatorType.AVG);
aMap.addOp("Count", OperatorType.COUNT);
aMap.addOp("Min", OperatorType.MIN);
aMap.addOp("Max", OperatorType.MAX);
aMap.addOp("Median", OperatorType.MEDIAN);
aMap.addOp("Sum", OperatorType.SUM);
aMap.addOp("StdDev", OperatorType.STDDEV);
aMap.addOp("Variance", OperatorType.VARIANCE);
aMap.addOp("-", OperatorType.NEGATE);
aMap.addOp("^", OperatorType.POWER);
aMap.addOp("Round", OperatorType.ROUND);
aMap.addOp("Abs", OperatorType.ABS);
......
......@@ -12,7 +12,6 @@ import java.util.List;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.antlr.v4.runtime.tree.TerminalNodeImpl;
import org.cqframework.cql.gen.cqlLexer;
import org.cqframework.cql.gen.cqlParser;
......@@ -20,6 +19,7 @@ import org.cqframework.cql.gen.cqlParser.AdditionExpressionTermContext;
import org.cqframework.cql.gen.cqlParser.AliasedQuerySourceContext;
import org.cqframework.cql.gen.cqlParser.AndExpressionContext;
import org.cqframework.cql.gen.cqlParser.BeforeOrAfterIntervalOperatorPhraseContext;
import org.cqframework.cql.gen.cqlParser.BooleanLiteralContext;
import org.cqframework.cql.gen.cqlParser.DateTimeLiteralContext;
import org.cqframework.cql.gen.cqlParser.DateTimePrecisionContext;
import org.cqframework.cql.gen.cqlParser.EqualityExpressionContext;
......@@ -33,6 +33,8 @@ import org.cqframework.cql.gen.cqlParser.IntervalOperatorPhraseContext;
import org.cqframework.cql.gen.cqlParser.InvocationContext;
import org.cqframework.cql.gen.cqlParser.InvocationExpressionTermContext;
import org.cqframework.cql.gen.cqlParser.InvocationTermContext;
import org.cqframework.cql.gen.cqlParser.ListSelectorContext;
import org.cqframework.cql.gen.cqlParser.ListSelectorTermContext;
import org.cqframework.cql.gen.cqlParser.LiteralTermContext;
import org.cqframework.cql.gen.cqlParser.MemberInvocationContext;
import org.cqframework.cql.gen.cqlParser.MultipleSourceClauseContext;
......@@ -42,6 +44,7 @@ import org.cqframework.cql.gen.cqlParser.NumberLiteralContext;
import org.cqframework.cql.gen.cqlParser.ParamListContext;
import org.cqframework.cql.gen.cqlParser.ParenthesizedTermContext;
import org.cqframework.cql.gen.cqlParser.PluralDateTimePrecisionContext;
import org.cqframework.cql.gen.cqlParser.PolarityExpressionTermContext;
import org.cqframework.cql.gen.cqlParser.PowerExpressionTermContext;
import org.cqframework.cql.gen.cqlParser.QualifiedIdentifierContext;
import org.cqframework.cql.gen.cqlParser.QualifierContext;
......@@ -64,6 +67,7 @@ import org.cqframework.cql.gen.cqlParser.TermContext;
import org.cqframework.cql.gen.cqlParser.TermExpressionContext;
import org.cqframework.cql.gen.cqlParser.TermExpressionTermContext;
import org.cqframework.cql.gen.cqlParser.TerminologyContext;
import org.cqframework.cql.gen.cqlParser.TimeLiteralContext;
import org.cqframework.cql.gen.cqlParser.TimingExpressionContext;
import org.cqframework.cql.gen.cqlParser.TupleElementSelectorContext;
import org.cqframework.cql.gen.cqlParser.TupleSelectorContext;
......@@ -79,6 +83,7 @@ import de.uniwue.query.GraphPath;
import de.uniwue.query.GraphQuery;
import de.uniwue.query.OperatorType;
import de.uniwue.query.Primitive;
import de.uniwue.query.Primitive.PrimitiveDataType;
import de.uniwue.query.PrimitiveDateTime;
import de.uniwue.query.QueryConcept;
import de.uniwue.query.QueryOperator;
......@@ -141,6 +146,7 @@ public class CQL_2_Graph_Mapper {
public GraphQuery parse(String aQueryString) throws IOException {
clear();
ExpressionContext e = parseWithAntlr(aQueryString);
currentOp = query.rootClause;
parseExpression(e);
addLeafsToRootClause();
addDefaultReturnIfNecessary();
......@@ -241,7 +247,7 @@ public class CQL_2_Graph_Mapper {
QueryOperator lastCreatedOp = parseExpression(expression);
if (lastCreatedOp != null) {
lastCreatedOp.includeInResult = true;
lastCreatedOp.outputName = text;
lastCreatedOp.outputName = text;
} else if (currentPath != null) {
QueryConcept lastElement = currentPath.getLastElement();
lastElement.includeInResult = true;
......@@ -535,6 +541,8 @@ public class CQL_2_Graph_Mapper {
} else {
throw new RuntimeException("unexpected");
}
} else if (te instanceof PolarityExpressionTermContext) {
thisOp = addOp(OperatorType.NEGATE);
} else if ((te instanceof TermExpressionTermContext)
|| (te instanceof InvocationExpressionTermContext)) {
// these only have children, which are handled below
......@@ -550,7 +558,8 @@ public class CQL_2_Graph_Mapper {
return thisOp;
}
private QueryOperator parseExpressionTermChildren(ExpressionTermContext te, boolean isDotInvocation) {
private QueryOperator parseExpressionTermChildren(ExpressionTermContext te,
boolean isDotInvocation) {
QueryOperator lastCreatedOp = null;
for (ParseTree aChild : te.children) {
String prettyPrint2 = prettyPrint(aChild);
......@@ -573,6 +582,9 @@ public class CQL_2_Graph_Mapper {
} else if (aChild instanceof LiteralTermContext) {
LiteralTermContext lt = (LiteralTermContext) aChild;
parseLiteralTermContext(lt);
} else if (aChild instanceof ListSelectorTermContext) {
ListSelectorTermContext lst = (ListSelectorTermContext) aChild;
lastCreatedOp = parseListSelectorTermContext(lst);
} else if (aChild instanceof InvocationTermContext) {
InvocationTermContext it = (InvocationTermContext) aChild;
InvocationContext invocation = it.invocation();
......@@ -596,6 +608,14 @@ public class CQL_2_Graph_Mapper {
return lastCreatedOp;
}
private QueryOperator parseListSelectorTermContext(ListSelectorTermContext lst) {
String prettyPrint = prettyPrint(lst);
ListSelectorContext listSelector = lst.listSelector();
List<ExpressionContext> expression = listSelector.expression();
QueryOperator newOp = parseOpWithParams(expression, OperatorType.LIST);
return newOp;
}
private boolean containsFunctionCall(InvocationExpressionTermContext iet) {
ExpressionTermContext expressionTerm = iet.expressionTerm();
if (expressionTerm instanceof TermExpressionTermContext) {
......@@ -647,35 +667,43 @@ public class CQL_2_Graph_Mapper {
String prettyPrint = prettyPrint(invocation);
if (invocation instanceof MemberInvocationContext) {
MemberInvocationContext mi = (MemberInvocationContext) invocation;
parseMemberInvocationContext(mi);
parseMemberInvocationContext(mi);
return null;
} else if (invocation instanceof FunctionInvocationContext) {
FunctionInvocationContext fi = (FunctionInvocationContext) invocation;
FunctionContext function = fi.function();
String text = function.identifier().getText();
String text = function.identifier().getText().toLowerCase();
OperatorType opType;
if (text.equals("Exp")) {
if (text.equals("exp")) {
opType = OperatorType.EXP;
} else if (text.equals("Log")) {
} else if (text.equals("log")) {
opType = OperatorType.LOG;
} else if (text.equals("Ln")) {
} else if (text.equals("ln")) {
opType = OperatorType.LN;
} else if (text.equals("Round")) {
} else if (text.equals("round")) {
opType = OperatorType.ROUND;
} else if (text.equals("Abs")) {
} else if (text.equals("abs")) {
opType = OperatorType.ABS;
} else if (text.equals("Truncate")) {
} else if (text.equals("truncate")) {
opType = OperatorType.TRUNCATE;
} else if (text.equals("Floor")) {
} else if (text.equals("floor")) {
opType = OperatorType.FLOOR;
} else if (text.equals("Ceiling")) {
} else if (text.equals("ceiling")) {
opType = OperatorType.CEILING;
} else if (text.equals("Last")) {
} else if (text.equals("last")) {
opType = OperatorType.LAST;
} else if (text.equals("Count")) {
} else if (text.equals("count")) {
opType = OperatorType.COUNT;
} else if (text.equals("Avg")) {
} else if (text.equals("avg")) {
opType = OperatorType.AVG;
} else if (text.equals("alltrue")) {
opType = OperatorType.ALLTRUE;
} else if (text.equals("anytrue")) {
opType = OperatorType.ANYTRUE;
} else if (text.equals("max")) {
opType = OperatorType.MAX;
} else if (text.equals("min")) {
opType = OperatorType.MIN;
} else {
throw new RuntimeException("unexpected");
}
......@@ -742,6 +770,15 @@ public class CQL_2_Graph_Mapper {
DateTimeLiteralContext dtl = (DateTimeLiteralContext) aChild;
String text = dtl.DATETIME().getText();
parseDateTime(text);
} else if (aChild instanceof TimeLiteralContext) {
TimeLiteralContext tl = (TimeLiteralContext) aChild;
String text = tl.TIME().getText();
parseDateTime(text);
} else if (aChild instanceof BooleanLiteralContext) {
BooleanLiteralContext btl = (BooleanLiteralContext) aChild;
String text = btl.getText();
Primitive parameter = currentOp.addParameter(text);
parameter.dataType = PrimitiveDataType.Boolean;
} else {
throw new RuntimeException("unexpected");
}
......@@ -752,16 +789,18 @@ public class CQL_2_Graph_Mapper {
return aDateString.matches(format);
}
private SimpleDateFormat onlyYearsIn, dateTimeWithSecondsIn, yearsOut, monthsOut, daysOut,
private SimpleDateFormat onlyYearsIn, dateTimeWithSecondsIn, onlyTimeWithSecondsIn, yearsOut, monthsOut, daysOut,
hoursOut, minutesOut, secondsOut, milliSecsOut;
private String onlyYearsInRegex, dateTimeWithSecondsInRegex;
private String onlyYearsInRegex, dateTimeWithSecondsInRegex, onlyTimeWithSecondsInRegex;
private void initDateFormats() {
onlyYearsIn = new SimpleDateFormat("@yyyy");
onlyYearsInRegex = "^@\\d{4}$";
dateTimeWithSecondsIn = new SimpleDateFormat("@yyyy-MM-DD'T'HH:mm:ss");
dateTimeWithSecondsInRegex = "^@\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$";
onlyTimeWithSecondsIn = new SimpleDateFormat("@'T'HH:mm:ss");
onlyTimeWithSecondsInRegex = "^@T\\d{2}:\\d{2}:\\d{2}$";
yearsOut = new SimpleDateFormat("yyyy");
monthsOut = new SimpleDateFormat("MM");
daysOut = new SimpleDateFormat("DD");
......@@ -787,12 +826,16 @@ public class CQL_2_Graph_Mapper {
hasHours = true;
hasMinutes = true;
hasSeconds = true;
} else if (checkFormat(onlyTimeWithSecondsInRegex, dateTimeStringIn)) {
parse = onlyTimeWithSecondsIn.parse(dateTimeStringIn);
hasHours = true;
hasMinutes = true;
hasSeconds = true;
} else {
throw new RuntimeException("unknown format");
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
String yearValue = null, monthValue = null, dayValue = null, hourValue = null,
minuteValue = null, secondValue = null, millisecValue = null;
......@@ -901,17 +944,17 @@ public class CQL_2_Graph_Mapper {
QueryOperator lastOp = currentOp;
addOp(OperatorType.QUANTITY);
QuantityContext quantity = ql.quantity();
UnitContext unit = quantity.unit();
String text = quantity.NUMBER().getText();
parseNumber(text);
UnitContext unit = quantity.unit();
DateTimePrecisionContext dateTimePrecision = unit.dateTimePrecision();
PluralDateTimePrecisionContext pluralDateTimePrecision = unit.pluralDateTimePrecision();
TerminalNode string = unit.STRING();
if (pluralDateTimePrecision != null) {
String text2 = pluralDateTimePrecision.getText();
currentOp.addParameter(text2);
String timePrecision = pluralDateTimePrecision.getText();
currentOp.addParameter(timePrecision);
} else {
throw new RuntimeException("unexpected");
String unitString = unit.STRING().getText();
currentOp.addParameter(unitString);
}
currentOp = lastOp;
}
......
......@@ -66,19 +66,27 @@ public class Graph_2_CQL_Mapper extends Graph_2_System_Mapper {
public String visit(GraphQuery aQuery) {
initialize(aQuery);
StringBuilder builder = new StringBuilder();
builder.append("[" + getFirstRoot().code + "] ");
String alias = aliasNames[aliasIndex++];
builder.append(alias);
aliases.put(getFirstRoot(), alias);
String conceptsString = writeRootConcepts();
builder.append(conceptsString);
String where = writeWhere(query.rootClause);
if (!where.isEmpty()) {
builder.append(" where " + where);
}
String returnClause = writeReturn();
if (!returnClause.isEmpty()) {
builder.append(" return " + returnClause);
QueryConcept firstRoot = getFirstRoot();
if (firstRoot != null) {
builder.append("[" + firstRoot.code + "] ");
String alias = aliasNames[aliasIndex++];
builder.append(alias);
aliases.put(getFirstRoot(), alias);
String conceptsString = writeRootConcepts();
builder.append(conceptsString);
String where = writeWhere(query.rootClause);
if (!where.isEmpty()) {
builder.append(" where " + where);
}
String returnClause = writeReturn();
if (!returnClause.isEmpty()) {
builder.append(" return " + returnClause);
}
} else {
Set<Expression> returnedExpressions = query.getReturnedExpressions();
for (Expression anExp : returnedExpressions) {
builder.append(writeExpr(anExp));
}
}
return builder.toString().trim();
}
......@@ -359,6 +367,10 @@ public class Graph_2_CQL_Mapper extends Graph_2_System_Mapper {
} else if (anOp.type == OperatorType.INTERVAL) {
String intString = writeInterval(anOp);
builder.append(intString);
} else if ((anOp.type == OperatorType.NEGATE) && anOp.getParameters().get(0).isPrimitive()) {
builder.append("-");
String aPrim = writePrimitive(anOp.getParameters().get(0).asPrimitive());
builder.append(aPrim);
} else if (anOp.type == OperatorType.IN_VALUE_SET) {
String string1 = writeExpr(anOp.getParameters().get(0));
builder.append(string1);
......
......@@ -43,7 +43,11 @@ public class GraphQuery {
}
public QueryConcept getFirstRoot() {
return rootConcepts.get(0);
if (rootConcepts.size() > 0) {
return rootConcepts.get(0);
} else {
return null;
}
}
public String toString() {
......
......@@ -10,6 +10,9 @@ public enum OperatorType {
XOR,
NOT,
ALLTRUE,
ANYTRUE,
// comparators
EQUALS,
END,
......@@ -41,6 +44,12 @@ public enum OperatorType {
// aggregation
COUNT,
AVG,
MIN,
MAX,
MEDIAN,
SUM,
STDDEV,
VARIANCE,
// arithmetics
POWER,
......@@ -58,6 +67,7 @@ public enum OperatorType {
DIVIDE,
TRUNCATED_DIVIDE,
MODULO,
NEGATE,
// datetime
NOW,
......
......@@ -7,7 +7,7 @@ public class Primitive extends Expression {
public String value;
public enum PrimitiveDataType {
String, Integer, Double, DateTime
String, Integer, Double, DateTime, Boolean
}
public PrimitiveDataType dataType;
......
......@@ -26,7 +26,7 @@ public class Test_CQL_2_CQL {
initialize();
QueryManager queryManager = new QueryManager();
for (MultiQuery aMultiQuery : queryManager.queries) {
if (aMultiQuery.name.equals("query_CQL_Last3")) {
if (aMultiQuery.name.equals("query_CQL_define")) {
processQuery(aMultiQuery);
return;
}
......@@ -42,8 +42,8 @@ public class Test_CQL_2_CQL {
public static void main(String[] args) throws IOException, ParseException {
Test_CQL_2_CQL test = new Test_CQL_2_CQL();
// test.parseQueries();
test.debugTest();
// test.testCQL_2_CQL();
// test.debugTest();
test.testCQL_2_CQL();
}
private void processQuery(MultiQuery aMultiQuery) throws IOException {
......
......@@ -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_Last2")) {
if (aMultiQuery.name.equals("query_CQL_2_Cypher_Count2")) {
processQuery(aMultiQuery);
}
}
......@@ -63,8 +63,8 @@ public class Test_CQL_2_Cypher {
public static void main(String[] args) throws IOException, XMLStreamException, ParseException,
JDOMException, ParserConfigurationException, SAXException {
Test_CQL_2_Cypher test = new Test_CQL_2_Cypher();
test.debugTest();
// test.testCQL_2_Cypher();
// test.debugTest();
test.testCQL_2_Cypher();
}
@Test
......
*CQL
[Patient] A where Count(A.name N where Count(N.given) > 0) > 1
*Cypher
*CQL_antlr
expression
query
sourceClause
singleSourceClause
aliasedQuerySource
querySource
retrieve [
namedTypeSpecifier
identifier Patient
]
alias
identifier A
whereClause where
expression
expression
expressionTerm
term
invocation
function
identifier Count
(
paramList
expression
query
sourceClause
singleSourceClause
aliasedQuerySource
querySource
qualifiedIdentifier
qualifier
identifier A
.
identifier name
alias
identifier N
whereClause where
expression
expression
expressionTerm
term
invocation
function
identifier Count
(
paramList
expression
expressionTerm
expressionTerm
term
invocation
identifier N
.
invocation
identifier given
)
>
expression
expressionTerm
term
literal 0
)
>
expression
expressionTerm
term
literal 1
\ No newline at end of file
*CQL
[Patient] A define x:[Patient] A
[Observation] A
[Patient] B
*CQL_XML
*CQL
library ChlamydiaScreening_CQM version '2'
using QUICK
define "x" : [Patient] A
[Patient] B
*CQL_XML
*CQL
alltrue({ true, true, true })
*CQL2
alltrue({ true, true, true })
*CQL
anytrue({ false, true, false })
*CQL2
anytrue({ false, true, false })
*CQL
Avg({ 1.0, 2.0, 3.0, 4.0 })
*CQL2
Avg({ 1, 2, 3, 4 })
*Comment
// is it correct to transform the decimals to ints ?
*CQL
Avg({ 1 'm', 2 'm', 3 'm', 4 'm' })
*CQL2
Avg({ 1 'm', 2 'm', 3 'm', 4 'm' })
*CQL
Max({ @2012-01-01T00:00:00, @2013-01-01T00:00:00, @2014-01-01T00:00:00, @2015-01-01T00:00:00 })
*CQL2
Max({ @2012-01-01T00:00:00, @2013-01-01T00:00:00, @2014-01-01T00:00:00, @2015-01-01T00:00:00 })
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment