Commit 7e5bdf95 authored by Georg Fette's avatar Georg Fette
Browse files

finished a lot of refactoring

still has to tidy up a lot
at least most test cases except the cypher transformations work again
parent 43d8e333
......@@ -82,7 +82,6 @@ import org.cqframework.cql.gen.cqlParser.WhereClauseContext;
import org.cqframework.cql.gen.cqlParser.WithClauseContext;
import de.uniwue.misc.util.RegexUtil;
import de.uniwue.query.Expression;
import de.uniwue.query.OperatorType;
import de.uniwue.query.Primitive;
import de.uniwue.query.Primitive.PrimitiveDataType;
......@@ -216,11 +215,12 @@ public class CQL_2_Graph_Mapper extends System_2_Graph_Mapper {
private void parseReturnClauseContext(ReturnClauseContext returnClause) {
String prettyPrint = prettyPrint(returnClause);
currentOp = query;
addOp(OperatorType.RETURN);
parsingReturnRoot = true;
TermExpressionContext te = (TermExpressionContext) returnClause.expression();
TermExpressionTermContext tet = (TermExpressionTermContext) te.expressionTerm();
TermContext term = tet.term();
List<Expression> formerReturns = new ArrayList<Expression>(query.getParameters());
if (term instanceof TupleSelectorTermContext) {
TupleSelectorTermContext tst = (TupleSelectorTermContext) term;
TupleSelectorContext tupleSelector = tst.tupleSelector();
......@@ -236,21 +236,16 @@ public class CQL_2_Graph_Mapper extends System_2_Graph_Mapper {
} else {
throw new RuntimeException("unexpected");
}
for (Expression anExp : formerReturns) {
query.removeParameter(anExp);
}
}
private void parseTupleElementSelectorContext(TupleElementSelectorContext anElem) {
String prettyPrint = prettyPrint(anElem);
currentOp = null;
String text = anElem.identifier().getText();
ExpressionContext expression = anElem.expression();
QueryOperator lastCreatedOp = parseExpression(expression);
if (lastCreatedOp != null) {
lastCreatedOp.outputName = text;
} else if (lastPathElem != null) {
query.addParameter(lastPathElem);
lastPathElem.outputName = text;
} else {
throw new RuntimeException("unexpected");
......@@ -530,7 +525,12 @@ public class CQL_2_Graph_Mapper extends System_2_Graph_Mapper {
String prettyPrint = prettyPrint(ae);
QueryOperator lastOp = currentOp;
QueryOperator thisOp;
thisOp = addOp(OperatorType.AND);
// let nested ANDs be put into the same AND with unlimited parameter clauses
if (currentOp.type != OperatorType.AND) {
thisOp = addOp(OperatorType.AND);
} else {
thisOp = currentOp;
}
List<ExpressionContext> expression = ae.expression();
for (ExpressionContext ec : expression) {
parseExpression(ec);
......@@ -841,7 +841,7 @@ public class CQL_2_Graph_Mapper extends System_2_Graph_Mapper {
String prettyPrint = prettyPrint(mi);
String text = mi.identifier().getText();
if (lastPathElem == null) {
if (currentOp.type == OperatorType.FIELD) {
if ((currentOp != null) && (currentOp.type == OperatorType.FIELD)) {
currentOp.addParameter(text);
return currentOp;
} else {
......
......@@ -26,7 +26,8 @@ public abstract class Expression {
if (isOperator()) {
QueryOperator thisAsOp = asOperator();
if ((thisAsOp.type == OperatorType.ITERATE) || (thisAsOp.type == OperatorType.FIELD)
|| (thisAsOp.type == OperatorType.FIELD_WITH_TYPE)) {
|| (thisAsOp.type == OperatorType.FIELD_WITH_TYPE)
|| (thisAsOp.type == OperatorType.ALIAS_REF)) {
return true;
}
}
......@@ -45,4 +46,6 @@ public abstract class Expression {
return (QueryOperator) this;
}
public abstract Expression clone();
}
......@@ -34,4 +34,9 @@ public class Primitive extends Expression {
return result;
}
public Primitive clone() {
Primitive result = new Primitive(value);
result.dataType = dataType;
return result;
}
}
......@@ -20,6 +20,16 @@ public class QueryOperator extends Expression {
}
}
public QueryOperator(QueryOperator aContainerOp, OperatorType opType, boolean insertInChainForContainer) {
this.type = opType;
if (aContainerOp != null) {
parent = aContainerOp.parent;
QueryOperator tmp = aContainerOp.parent;
tmp.removeParameter(aContainerOp);
tmp.addParameter(this);
}
}
public QueryOperator(QueryOperator aContainerOp, String conceptCode) {
this(aContainerOp, OperatorType.ITERATE);
Primitive primitive = new Primitive(conceptCode);
......@@ -65,6 +75,14 @@ public class QueryOperator extends Expression {
this(null, opType);
}
public QueryOperator clone() {
QueryOperator result = new QueryOperator(type);
for (Expression anExp : getParameters()) {
result.addParameter(anExp.clone());
}
return result;
}
public void clear() {
parameters.clear();
}
......@@ -97,9 +115,15 @@ public class QueryOperator extends Expression {
}
public void checkConsistency() {
if ((parent != null) && !parent.getParameters().contains(this)) {
throw new RuntimeException("parent does not contain me");
checkDuplicateAliases();
checkParentChildSynchonicity();
checkAliasExistenceForAliasRefs();
for (QueryOperator anOp : getOperators()) {
anOp.checkConsistency();
}
}
private void checkAliasExistenceForAliasRefs() {
if (type == OperatorType.ALIAS_REF) {
String alias = getParameters().get(0).asPrimitive().value;
boolean aliasExists = false;
......@@ -112,11 +136,32 @@ public class QueryOperator extends Expression {
throw new RuntimeException("ALIAS_REF has no matching alias");
}
}
for (QueryOperator anOp : getOperators()) {
anOp.checkConsistency();
}
private void checkParentChildSynchonicity() {
if ((parent != null) && !parent.getParameters().contains(this)) {
throw new RuntimeException("parent does not contain me");
}
}
private void checkDuplicateAliases() {
if (isRoot()) {
for (QueryOperator anOp : getRoot().getOpsRecursive()) {
if (anOp.alias != null) {
for (QueryOperator anOp2 : getRoot().getOpsRecursive()) {
if ((anOp.alias != null) && (anOp != anOp2) && anOp.alias.equals(alias)) {
throw new RuntimeException("alias '" + anOp.alias + "' appear multiple times");
}
}
}
}
}
}
public boolean isRoot() {
return parent == null;
}
public List<Expression> getParameters() {
return new ArrayList<Expression>(parameters);
}
......@@ -173,6 +218,11 @@ public class QueryOperator extends Expression {
aParameter.parent = this;
}
public void addParameter(Expression aParameter, int index) {
this.parameters.add(index, aParameter);
aParameter.parent = this;
}
public void removeParameter(Expression aParameter) {
parameters.remove(aParameter);
aParameter.parent = null;
......@@ -250,17 +300,45 @@ public class QueryOperator extends Expression {
}
public QueryOperator getParentConcept() {
if (!isIterator()) {
return null;
if (!isConcept()) {
throw new RuntimeException("no concept");
}
if (type == OperatorType.ITERATE) {
if (type == OperatorType.ALIAS_REF) {
QueryOperator opReferencedWithAlias = resolveAlias();
return opReferencedWithAlias.getParentConcept();
} else if (type == OperatorType.ITERATE) {
// I have no parent because I am a root concept
return null;
}
String aliasRefValue = getParameters().get(0).asOperator().getParameters().get(0)
.asPrimitive().value;
for (QueryOperator anOp : getRoot().getOpsRecursive()) {
if ((anOp.alias != null) && anOp.alias.equals(aliasRefValue)) {
QueryOperator aliasedOp = getRoot().getOpWithAlias(aliasRefValue);
return aliasedOp;
}
public QueryOperator resolveAlias() {
if (type != OperatorType.ALIAS_REF) {
return this;
}
String alias = getParameters().get(0).asPrimitive().value;
QueryOperator opWithAlias = getOpWithAlias(alias);
return opWithAlias;
}
public List<QueryOperator> getAliasRefsWithAlias(String anAlias) {
List<QueryOperator> result = new ArrayList<QueryOperator>();
for (QueryOperator anAliasRef : getOpsRecursiveWithType(OperatorType.ALIAS_REF)) {
if (anAliasRef.getParameters().get(0).asPrimitive().value.equals(anAlias)) {
result.add(anAliasRef);
}
}
return result;
}
public QueryOperator getOpWithAlias(String anAlias) {
List<QueryOperator> ops = getRoot().getOpsRecursive();
for (QueryOperator anOp : ops) {
if ((anOp.alias != null) && anOp.alias.equals(anAlias)) {
return anOp;
}
}
......@@ -310,4 +388,12 @@ public class QueryOperator extends Expression {
}
}
public void removeUnnecessaryANDs() {
for (QueryOperator anAnd : getRoot().getOpsRecursiveWithType(OperatorType.AND)) {
if (anAnd.getParameters().size() == 1) {
anAnd.parent.addParameter(anAnd.getParameters().get(0));
anAnd.parent.removeParameter(anAnd);
}
}
}
}
......@@ -103,7 +103,7 @@ public class AQL_2_Graph_Mapper extends System_2_Graph_Mapper {
currentOp = query;
visitQueryExpr(parseTree);
moveClausesToOutmostEncapsulatingClauses();
removeUnnecessaryANDs();
query.removeUnnecessaryANDs();
return query;
}
......@@ -165,7 +165,7 @@ public class AQL_2_Graph_Mapper extends System_2_Graph_Mapper {
if (nearestFilter != targetClause) {
aFilter.parent.removeParameter(aFilter);
if (targetClause.getParameters().size() > 1) {
currentOp = targetClause.getParameters().get(1).asOperator();
currentOp = targetClause.getParameters().get(1).asOperator();
if (currentOp.type != OperatorType.AND) {
targetClause = insertOp(OperatorType.AND);
}
......@@ -182,15 +182,6 @@ public class AQL_2_Graph_Mapper extends System_2_Graph_Mapper {
return currentOp;
}
private void removeUnnecessaryANDs() {
for (QueryOperator anAnd : query.getOpsRecursiveWithType(OperatorType.AND)) {
if (anAnd.getParameters().size() == 1) {
anAnd.parent.addParameter(anAnd.getParameters().get(0));
anAnd.parent.removeParameter(anAnd);
}
}
}
private void visitPredicateOperandContexts(List<PredicateOperandContext> predicateOperand,
TerminalNode comparableoperator) {
QueryOperator lastOp = currentOp;
......
......@@ -6,6 +6,7 @@ import java.util.List;
import org.springframework.core.io.Resource;
import de.uniwue.misc.util.ResourceUtil;
import de.uniwue.query.OperatorType;
import de.uniwue.query.QueryOperator;
public class CodeMapper extends GraphTransformation {
......@@ -14,6 +15,8 @@ public class CodeMapper extends GraphTransformation {
public String targetCode;
public String targetAccessOverride;
public CodeMapper(String sourceCode, String targetCode) {
this.sourceCode = sourceCode;
this.targetCode = targetCode;
......@@ -24,6 +27,9 @@ public class CodeMapper extends GraphTransformation {
for (QueryOperator aConcept : query.getIteratorsRecursive()) {
if (sourceCode.equals(aConcept.getIteratorSelector())) {
aConcept.setIteratorSelector(targetCode);
if (targetAccessOverride != null) {
aConcept.type = OperatorType.valueOf(targetAccessOverride);
}
}
}
}
......@@ -49,6 +55,10 @@ public class CodeMapper extends GraphTransformation {
String sourceCode = tokens[0];
String targetCode = tokens[1];
CodeMapper mapper = new CodeMapper(sourceCode, targetCode);
if (tokens.length > 2) {
String targetAccessOverride = tokens[2];
mapper.targetAccessOverride = targetAccessOverride;
}
transformations.add(mapper);
}
}
......
......@@ -9,32 +9,27 @@ public class Equality_2_Meronym_Transformation extends GraphTransformation {
@Override
public void transform(QueryOperator query) {
for (QueryOperator anOp : query.getOpsRecursive()) {
if (anOp.type == OperatorType.EQUALS) {
List<QueryOperator> conceptParam = anOp.getChildConcepts();
if (conceptParam.size() != 2) {
continue;
}
QueryOperator newHolonymConc = null, newMeronymConc = null, oldEqualityMember = null;
if (conceptParam.get(0).parent != null) {
newHolonymConc = conceptParam.get(0);
oldEqualityMember = conceptParam.get(1);
newMeronymConc = oldEqualityMember.parent;
} else if (conceptParam.get(1).parent != null) {
newHolonymConc = conceptParam.get(1);
oldEqualityMember = conceptParam.get(0);
newMeronymConc = oldEqualityMember.parent;
}
if (newHolonymConc != null) {
newHolonymConc.addParameter(newMeronymConc);
newMeronymConc.removeParameter(oldEqualityMember);
throw new RuntimeException("TODO");
// if (newMeronymConc.includeInResult) {
// query.rootClause.addParameter(newMeronymConc);
// }
// anOp.source.removeParameter(anOp);
// query.rootConcepts.remove(newMeronymConc);
}
for (QueryOperator anEquals : query.getOpsRecursiveWithType(OperatorType.EQUALS)) {
List<QueryOperator> conceptParam = anEquals.getChildConcepts();
if (conceptParam.size() != 2) {
continue;
}
QueryOperator newHolonymConc = null, oldEqualityMember = null;
if (conceptParam.get(0).getParentConcept() != null) {
newHolonymConc = conceptParam.get(0);
oldEqualityMember = conceptParam.get(1).resolveAlias();
} else if (conceptParam.get(1).getParentConcept() != null) {
newHolonymConc = conceptParam.get(1);
oldEqualityMember = conceptParam.get(0).resolveAlias();
}
if (newHolonymConc != null) {
QueryOperator parentConc = newHolonymConc.getParameters().get(0).asOperator()
.resolveAlias();
parentConc.type = OperatorType.FIELD_WITH_TYPE;
QueryOperator aliasRef = new QueryOperator(OperatorType.ALIAS_REF);
aliasRef.addParameter(oldEqualityMember.alias);
parentConc.addParameter(aliasRef, 0);
anEquals.parent.removeParameter(anEquals);
}
}
}
......
......@@ -15,10 +15,15 @@ public class Meronym_2_Equality_Transformation extends GraphTransformation {
@Override
public void transform(QueryOperator query) {
for (QueryOperator aConc : query.getIteratorsRecursive()) {
for (QueryOperator aChild : aConc.getChildConcepts()) {
if (parentCode.equals(aConc.getIteratorSelector()) && childCode.equals(aChild.getIteratorSelector())) {
transformMeronym_2_Equality(query, aConc, aChild);
List<QueryOperator> parents = query.getIteratorsWithSelector(parentCode);
for (QueryOperator aParent : parents) {
List<QueryOperator> children = query.getIteratorsWithSelector(childCode);
for (QueryOperator aChild : children) {
if (aChild.type == OperatorType.FIELD) {
QueryOperator aliasRef = aChild.getParameters().get(0).asOperator();
if (aParent == aliasRef.resolveAlias()) {
transformMeronym_2_Equality(query, aParent, aChild);
}
}
}
}
......@@ -26,17 +31,28 @@ public class Meronym_2_Equality_Transformation extends GraphTransformation {
protected void transformMeronym_2_Equality(QueryOperator query, QueryOperator parent,
QueryOperator child) {
parent.removeParameter(child);
query.getRootConcepts().add(child);
String newChildSelectorMemberName = null;
QueryOperator newMember = null;
if (parentCode.equals(parent.getIteratorSelector()) && childCode.equals(child.getIteratorSelector())) {
newMember = new QueryOperator(child.parent, child, child2parent_member);
child.type = OperatorType.ITERATE;
child.removeParameter(child.getParameters().get(0));
QueryOperator targetClauseContainer;
if (child.parent.getParameters().size() == 1) {
targetClauseContainer = child.parent;
} else {
QueryOperator existingClause = child.parent.getParameters().get(1).asOperator();
if (existingClause.type == OperatorType.AND) {
targetClauseContainer = existingClause;
} else {
QueryOperator newAnd = new QueryOperator(child.parent, OperatorType.AND);
child.parent.removeParameter(existingClause);
newAnd.addParameter(existingClause);
targetClauseContainer = newAnd;
}
}
QueryOperator equals = new QueryOperator(OperatorType.EQUALS);
query.addParameter(equals);
equals.addParameter(newMember);
equals.addParameter(parent);
QueryOperator equals = new QueryOperator(targetClauseContainer, OperatorType.EQUALS);
QueryOperator aliasRefToChild = new QueryOperator(equals, OperatorType.ALIAS_REF);
aliasRefToChild.addParameter(child.alias);
QueryOperator newMember = new QueryOperator(equals, aliasRefToChild, child2parent_member);
QueryOperator aliasRefToParent = new QueryOperator(equals, OperatorType.ALIAS_REF);
aliasRefToParent.addParameter(parent.alias);
}
public static void loadMeronym_2_Equality_Transformation(
......
......@@ -3,9 +3,8 @@ package de.uniwue.query.transform;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.core.io.Resource;
import de.uniwue.misc.util.ResourceUtil;
......@@ -14,9 +13,11 @@ import de.uniwue.query.QueryOperator;
public class PathTransformator extends GraphTransformation {
public String sourceCode, targetCode;
public String sourceCode, targetCode, intermediateCode;
boolean targetIsArray, intermediateIsArray;
public List<String> pathElems = new ArrayList<String>();
public String operation;
private List<String> aliasNames;
......@@ -33,6 +34,64 @@ public class PathTransformator extends GraphTransformation {
aliasIndex = 0;
}
private void removeIntermediateNonArrayField(QueryOperator query, QueryOperator aSourceConcept,
QueryOperator aTargetConcept) {
if (aTargetConcept.type == OperatorType.FIELD) {
QueryOperator innerAccess = aTargetConcept.getParameters().get(0).asOperator();
if ((innerAccess.type == OperatorType.FIELD)
&& (innerAccess.getParameters().get(1).asPrimitive().value
.equals(intermediateCode))) {
// remove the intermediate link
aTargetConcept.removeParameter(innerAccess);
// add the access to the ALIAS_REF
aTargetConcept.addParameter(innerAccess.getParameters().get(0), 0);
}
}
}
private void removeIntermediateArrayField(QueryOperator query, QueryOperator aSourceConcept,
QueryOperator aTargetConcept) {
QueryOperator targetFilter = aTargetConcept.parent;
QueryOperator firstFilterClause = aSourceConcept.parent.getParameters().get(1).asOperator();
QueryOperator pathPartToReplace = firstFilterClause;
if (firstFilterClause.type == OperatorType.AND) {
for (QueryOperator anAndChild : firstFilterClause.getOperators()) {
if (anAndChild.getIteratorsWithSelector(targetCode).contains(aTargetConcept)) {
pathPartToReplace = anAndChild;
}
}
}
QueryOperator parent = pathPartToReplace.parent;
// the aliases have to be kept synchronized
String alias = pathPartToReplace.getParameters().get(0).alias;
parent.removeParameter(pathPartToReplace);
QueryOperator currentFilter = parent;
QueryOperator currentConcept = currentFilter.getParameters().get(0).asOperator();
for (QueryOperator aliasRef : aSourceConcept.getRoot()
.getOpsRecursiveWithType(OperatorType.ALIAS_REF)) {
if (aliasRef.getParameters().get(0).asPrimitive().value.equals(alias)) {
aliasRef.getParameters().get(0).asPrimitive().value = aSourceConcept.alias;
}
}
}
private void addIntermediateNonArrayField(QueryOperator query, QueryOperator aSourceConcept,
QueryOperator aTargetConcept) {
}
private void addIntermediateArrayField(QueryOperator query, QueryOperator aSourceConcept,
QueryOperator aTargetConcept) {
QueryOperator sourceFilter = aSourceConcept.parent;
QueryOperator newFilter = new QueryOperator(sourceFilter, OperatorType.EXISTS);
QueryOperator currentConcept = new QueryOperator(newFilter, aSourceConcept, intermediateCode,
true);
String newAlias = aliasNames.get(aliasIndex++);
currentConcept.alias = newAlias;
aTargetConcept.parent.getParameters().get(0).asOperator().getParameters().get(0).asOperator()
.getParameters().get(0).asPrimitive().value = newAlias;
}
@Override
public void transform(QueryOperator query) {
initializeNewAliasNames(query);
......@@ -41,36 +100,17 @@ public class PathTransformator extends GraphTransformation {
QueryOperator sourceFilter = aSourceConcept.parent;
List<QueryOperator> targetConcepts = sourceFilter.getIteratorsWithSelector(targetCode);
for (QueryOperator aTargetConcept : targetConcepts) {
QueryOperator targetFilter = aTargetConcept.parent;
QueryOperator firstFilterClause = sourceFilter.getParameters().get(1).asOperator();
QueryOperator pathPartToReplace = firstFilterClause;
if (firstFilterClause.type == OperatorType.AND) {
for (QueryOperator anAndChild : firstFilterClause.getOperators()) {
if (anAndChild.getIteratorsWithSelector(targetCode).contains(aTargetConcept)) {
pathPartToReplace = anAndChild;
}
if (intermediateIsArray) {
if (operation.equals("remove")) {
removeIntermediateArrayField(query, aSourceConcept, aTargetConcept);
} else {
addIntermediateArrayField(query, aSourceConcept, aTargetConcept);
}
}
QueryOperator parent = pathPartToReplace.parent;
// the aliases have to be kept synchronized
String alias = pathPartToReplace.getParameters().get(0).alias;
parent.removeParameter(pathPartToReplace);
QueryOperator currentFilter = parent;
QueryOperator currentConcept = currentFilter.getParameters().get(0).asOperator();
for (String aPathElem : pathElems) {
currentFilter = new QueryOperator(currentFilter, OperatorType.EXISTS);
currentConcept = new QueryOperator(currentFilter, currentConcept, aPathElem, true);
String newAlias = aliasNames.get(aliasIndex++);
currentConcept.alias = newAlias;
targetFilter.getParameters().get(0).asOperator().getParameters().get(0).asOperator()
.getParameters().get(0).asPrimitive().value = newAlias;
}
currentFilter.addParameter(targetFilter);
if (pathElems.size() == 0) {
for (QueryOperator aliasRef : query.getOpsRecursiveWithType(OperatorType.ALIAS_REF)) {
if (aliasRef.getParameters().get(0).asPrimitive().value.equals(alias)) {
aliasRef.getParameters().get(0).asPrimitive().value = aSourceConcept.alias;
}
} else {
if