Skip to content

Commit

Permalink
Model combined UNION queries as a sequence of SingleQuery's
Browse files Browse the repository at this point in the history
This also pushes `union` and `singleQuery` properties down from the RegularQuery
to the new CombinedQuery interface.
This way, SingleQuery is cleaned from those unused properties.

When 3 or more SingleQueries built up a union query, it used to be modeled
as a tree where each union node added one more SingleQuery like

```
S1
UNION
S2
UNION
S3
```

was modeled as

```
RegularQuery
 +-singleQuery: RegularQuery
 | +-singleQuery: SingleQuery S1
 | +-union:
 |   +-[list entry]: Union
 |     +-singleQuery: SingleQuery S2
 +-union:
   +-list entry: Union
     +-singleQuery: SingleQuery S3
```

From now, the representation is as follows, where RegularQuery has 2 subclasses:
 - SingleQuery used for sole queries not having any UNION clauses
 - CombinedQuery used for queries that have at least one query combinator
   (UNION in current openCypher, but other set combinators like INTERSECT
   are about to come, see opencypher/openCypher#227)

```
CombinedQuery
 +-singleQuery: SingleQuery S1
 +-union:
   +-[list entry]: Union
     +-singleQuery: SingleQuery S2
   +-[list entry]: Union
     +-singleQuery: SingleQuery S3
```
  • Loading branch information
jmarton committed Dec 29, 2017
1 parent abe9746 commit 38a6771
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
package org.slizaa.neo4j.opencypher.ui.outline

import org.eclipse.xtext.EcoreUtil2
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
import org.eclipse.xtext.ui.editor.outline.IOutlineNode
import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider
import org.eclipse.xtext.ui.editor.outline.impl.DocumentRootNode
import org.slizaa.neo4j.opencypher.openCypher.Cypher
import org.slizaa.neo4j.opencypher.openCypher.CombinedQuery
import org.slizaa.neo4j.opencypher.openCypher.SingleQuery
import org.slizaa.neo4j.opencypher.openCypher.Statement
import org.slizaa.neo4j.opencypher.openCypher.Clause
Expand All @@ -26,24 +29,32 @@ class OpenCypherOutlineTreeProvider extends DefaultOutlineTreeProvider {

for (element : EcoreUtil2.getAllContentsOfType(cypher, Statement)) {

if (element instanceof SingleQuery) {
val SingleQuery singleQuery = element as SingleQuery;
if (singleQuery.union.size > 0) {
if (element instanceof CombinedQuery) {
val CombinedQuery combinedQuery = element as CombinedQuery;
val SingleQuery singleQuery = combinedQuery.singleQuery;
// TODO
// createNode(parentNode, singleQuery);
// val IOutlineNode singleQueryParent = NodeModelUtils.getNode(singleQuery);
// for (clause : singleQuery.clauses) {
// createNode(singleQueryParent, clause);
// }
} else {
for (clause : singleQuery.clauses) {
createNode(parentNode, clause);
}
}
// createNode(parentNode, combinedQuery);
// val IOutlineNode combinedQueryParent = NodeModelUtils.getNode(combinedQuery); //FIXME: getNode does not return IOutlineNode
// createNode(combinedQueryParent, singleQuery);
// val IOutlineNode singleQueryParent = NodeModelUtils.getNode(singleQuery); //FIXME: getNode does not return IOutlineNode
// _addSingleQueryClauses(singleQueryParent, singleQuery);
// for (_union : combinedQuery.union) {
// createNode(combinedQueryParent, _union.singleQuery);
// val IOutlineNode _unionParent = NodeModelUtils.getNode(_union.singleQuery); //FIXME: getNode does not return IOutlineNode
// _addSingleQueryClauses(_unionParent, _union.singleQuery);
// }
} else if (element instanceof SingleQuery) {
val SingleQuery singleQuery = element as SingleQuery;
_addSingleQueryClauses(parentNode, singleQuery);
} else {
createNode(parentNode, element);
}
}
}

def void _addSingleQueryClauses(IOutlineNode parentNode, SingleQuery singleQuery) {
for (clause : singleQuery.clauses) {
createNode(parentNode, clause);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Statement"/>
<eClassifiers xsi:type="ecore:EClass" name="Query" eSuperTypes="#//Statement"/>
<eClassifiers xsi:type="ecore:EClass" name="RegularQuery" eSuperTypes="#//Query">
<eStructuralFeatures xsi:type="ecore:EReference" name="singleQuery" eType="#//RegularQuery"
containment="true"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="union" upperBound="-1"
eType="#//Union" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="RegularQuery" eSuperTypes="#//Query"/>
<eClassifiers xsi:type="ecore:EClass" name="BulkImportQuery" eSuperTypes="#//Query">
<eStructuralFeatures xsi:type="ecore:EReference" name="periodicCommitHint" eType="#//PeriodicCommitHint"
containment="true"/>
Expand Down Expand Up @@ -456,6 +451,12 @@
<eStructuralFeatures xsi:type="ecore:EReference" name="cypherOption" upperBound="-1"
eType="#//CypherOption" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="CombinedQuery" eSuperTypes="#//RegularQuery">
<eStructuralFeatures xsi:type="ecore:EReference" name="singleQuery" eType="#//SingleQuery"
containment="true"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="union" upperBound="-1"
eType="#//Union" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="IndexHint" eSuperTypes="#//Hint">
<eStructuralFeatures xsi:type="ecore:EReference" name="variable" eType="#//Variable"
containment="true"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@
</genClasses>
<genClasses ecoreClass="OpenCypher.ecore#//Statement"/>
<genClasses ecoreClass="OpenCypher.ecore#//Query"/>
<genClasses ecoreClass="OpenCypher.ecore#//RegularQuery">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//RegularQuery/singleQuery"/>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//RegularQuery/union"/>
</genClasses>
<genClasses ecoreClass="OpenCypher.ecore#//RegularQuery"/>
<genClasses ecoreClass="OpenCypher.ecore#//BulkImportQuery">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//BulkImportQuery/periodicCommitHint"/>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//BulkImportQuery/loadCSVQuery"/>
Expand Down Expand Up @@ -339,6 +336,10 @@
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute OpenCypher.ecore#//AllOptions/profile"/>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//AllOptions/cypherOption"/>
</genClasses>
<genClasses ecoreClass="OpenCypher.ecore#//CombinedQuery">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//CombinedQuery/singleQuery"/>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//CombinedQuery/union"/>
</genClasses>
<genClasses ecoreClass="OpenCypher.ecore#//IndexHint">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//IndexHint/variable"/>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference OpenCypher.ecore#//IndexHint/nodeLabel"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ RegularQuery:
/*
* regularQuery : singleQuery ( ws union )* ;
*/
SingleQuery ({RegularQuery.singleQuery=current} union+=Union)*;
SingleQuery ({CombinedQuery.singleQuery=current} ( union+=Union )+ )? ;

BulkImportQuery:
/*
Expand Down

0 comments on commit 38a6771

Please sign in to comment.