Skip to content

Commit

Permalink
Fix and test bug generating SPARQL on union of two nodes where one is…
Browse files Browse the repository at this point in the history
… not the "head" because it has incoming (reverse) connections
  • Loading branch information
Paul Cuddihy committed Jan 25, 2021
1 parent f5e82cd commit fc7e379
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1736,6 +1736,7 @@ public String generateSparql(AutoGeneratedQueryTypes qt, Boolean allPropertiesOp
// #Error: explanation

this.buildPrefixHash();
this.updateUnionMemberships();

String retval = "";
String tab = SparqlToXUtils.tabIndent("");
Expand Down Expand Up @@ -1798,7 +1799,7 @@ public String generateSparql(AutoGeneratedQueryTypes qt, Boolean allPropertiesOp
Node headNode = this.getNextHeadNode(doneNodes);
while (headNode != null) {

Integer unionKey = this.getUnionKey(headNode);
Integer unionKey = this.getSubGraphUnionKey(headNode);
if (unionKey == null) {
sparql.append(this.generateSparqlSubgraphClausesNode( qt,
headNode,
Expand Down Expand Up @@ -2792,6 +2793,27 @@ public void unOptionalizeConstrained() throws Exception {
}
}

/**
* For an island subgraph, find 0 or 1 nodes with a top-level union key.
* That means that the whole island subgraph is a branch of a union.
*
* @param startNode
* @return unionKey or null
*/
private Integer getSubGraphUnionKey(Node startNode) {

for (Node node : this.getSubGraph(startNode, new ArrayList<Node>())) {
Integer unionKey = this.getUnionKey(node);
if (unionKey != null) {
ArrayList<Integer> membership = this.getUnionMembershipList(node);
if (membership.size() == 1) {
return membership.get(0);
}
}
}
return null;
}

/**
* Recursively find a subgraph given a node and a list of nodes who can't be in the subgraph
* @param startNode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,23 @@ public void unionTwoNodeItems() throws Exception {
assertEquals(2, tab.getNumRows());
}

@Test
/**
* Union of two nodes, where one isn't the "head node" because it has an incoming reverse minus
* @throws Exception
*/
public void unionTwoNodeItemsNonHead() throws Exception {

NodeGroup ng = TestGraph.getNodeGroup("src/test/resources/chain_node_minus_union.json");

String select = ng.generateSparql(AutoGeneratedQueryTypes.QUERY_DISTINCT, null, 10, null);
SparqlEndpointInterface sei = sgJson.getSparqlConn().getDefaultQueryInterface();
TableResultSet tRes = (TableResultSet) sei.executeQueryAndBuildResultSet(select, SparqlResultTypes.TABLE);

Table tab = tRes.getTable();
assertEquals(9, tab.getNumRows());
}

@Test
public void unionTwoPropItems() throws Exception {

Expand Down
155 changes: 155 additions & 0 deletions sparqlGraphLibrary/src/test/resources/chain_node_minus_union.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{
"version": 2,
"sparqlConn": {
"name": "Junit localhost virt",
"domain": "",
"enableOwlImports": true,
"model": [
{
"type": "virtuoso",
"url": "http://localhost:8890/sparql",
"graph": "http://junit/GG2NQYY2E/200001934/both"
}
],
"data": [
{
"type": "virtuoso",
"url": "http://localhost:8890/sparql",
"graph": "http://junit/GG2NQYY2E/200001934/both"
}
]
},
"sNodeGroup": {
"version": 12,
"limit": 0,
"offset": 0,
"sNodeList": [
{
"propList": [
{
"KeyName": "linkName",
"ValueType": "string",
"relationship": "http://www.w3.org/2001/XMLSchema#string",
"UriRelationship": "http://kdl.ge.com/junit/chain#linkName",
"Constraints": "",
"fullURIName": "",
"SparqlID": "?linkName_0",
"isReturned": false,
"optMinus": 0,
"isRuntimeConstrained": false,
"instanceValues": [],
"isMarkedForDeletion": false,
"binding": "?linkName",
"isBindingReturned": true
}
],
"nodeList": [],
"NodeName": "Link",
"fullURIName": "http://kdl.ge.com/junit/chain#Link",
"SparqlID": "?Link_0",
"isReturned": false,
"isRuntimeConstrained": false,
"valueConstraint": "",
"instanceValue": null,
"deletionMode": "NO_DELETE",
"binding": "?Link",
"isBindingReturned": false
},
{
"propList": [],
"nodeList": [
{
"SnodeSparqlIDs": [
"?Link_0"
],
"OptionalMinus": [
-2
],
"Qualifiers": [
""
],
"DeletionMarkers": [
false
],
"KeyName": "firstLink",
"ValueType": "Link",
"UriValueType": "http://kdl.ge.com/junit/chain#Link",
"ConnectBy": "firstLink",
"Connected": true,
"UriConnectBy": "http://kdl.ge.com/junit/chain#firstLink"
}
],
"NodeName": "Chain",
"fullURIName": "http://kdl.ge.com/junit/chain#Chain",
"SparqlID": "?Chain",
"isReturned": false,
"isRuntimeConstrained": false,
"valueConstraint": "",
"instanceValue": null,
"deletionMode": "NO_DELETE"
},
{
"propList": [
{
"KeyName": "linkName",
"ValueType": "string",
"relationship": "http://www.w3.org/2001/XMLSchema#string",
"UriRelationship": "http://kdl.ge.com/junit/chain#linkName",
"Constraints": "FILTER regex(%id, \"1$\")",
"fullURIName": "",
"SparqlID": "?linkName",
"isReturned": true,
"optMinus": 0,
"isRuntimeConstrained": false,
"instanceValues": [],
"isMarkedForDeletion": false
}
],
"nodeList": [],
"NodeName": "Link",
"fullURIName": "http://kdl.ge.com/junit/chain#Link",
"SparqlID": "?Link",
"isReturned": false,
"isRuntimeConstrained": false,
"valueConstraint": "",
"instanceValue": null,
"deletionMode": "NO_DELETE"
}
],
"orderBy": [],
"unionHash": {
"1": [
"?Link",
"?Link_0"
]
}
},
"importSpec": {
"version": "1",
"baseURI": "",
"columns": [],
"dataValidator": [],
"texts": [],
"transforms": [],
"nodes": [
{
"sparqlID": "?Link",
"type": "http://kdl.ge.com/junit/chain#Link",
"mapping": [],
"props": []
},
{
"sparqlID": "?Chain",
"type": "http://kdl.ge.com/junit/chain#Chain",
"mapping": [],
"props": []
},
{
"sparqlID": "?Link_0",
"type": "http://kdl.ge.com/junit/chain#Link",
"mapping": [],
"props": []
}
]
}
}

0 comments on commit fc7e379

Please sign in to comment.