Vishal
Vishal

Reputation: 31

MarkLogic returns incorrect results for a sparql query

MarkLogic returns incorrect results when a sparql query is executed in its query console.

Dummy data:

Scenario: There's a Folder object and it has child objects of type File. All objects have label. Each Folder/File has a relation called WritePermission which tells the Group that has permission to modify it.

prefix ex: <http://example.com/ns#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

insert data {
  ex:ID0 rdfs:label "Root" .
  ex:ID0 rdf:type ex:Folder .
  ex:ID0 ex:WritePermission ex:GROUP1 . 
  ex:ID1 rdfs:label "File1" .
  ex:ID1 rdf:type ex:File .
  ex:ID1 ex:Parent ex:ID0 .
  ex:ID1 ex:WritePermission ex:GROUP2 . 
  ex:ID2 rdfs:label "File2" .
  ex:ID2 rdf:type ex:File .
  ex:ID2 ex:Parent ex:ID0 .
  ex:ID2 ex:WritePermission ex:GROUP2 . 
  ex:ID3 rdfs:label "File3" .
  ex:ID3 rdf:type ex:File .
  ex:ID3 ex:Parent ex:ID0 .
  ex:ID3 ex:WritePermission ex:GROUP2 .
  ex:GROUP1 rdf:type ex:Group .
  ex:GROUP1 rdfs:label "Admin" .
  ex:GROUP1 ex:Member ex:USER1 .
  ex:GROUP2 rdf:type ex:Group .
  ex:GROUP2 rdfs:label "Users" .
  ex:GROUP2 ex:Member ex:USER2 .
  ex:USER1 rdf:type ex:User .
  ex:USER1 rdfs:label "User1" .
  ex:USER2 rdf:type ex:User .
  ex:USER2 rdfs:label "User2" .
}


Query:

Following query is expected to tell whether a given name already exists under given Parent ("Root"). Second exists clause checks whether an object belongs to a group which has write permission to the given Parent ID "Root".

prefix ex: <http://example.com/ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?nameConflict ?hasWritePermissionToParent
where { 
  bind(ex:ID0 as ?parent)
  bind("""ZZZ""" as ?nameToCheck)
  bind(ex:USER2 as ?userId)

  bind(exists { ?parent ^ex:Parent/rdfs:label ?nameToCheck } as ?nameConflict)
  bind(exists { ?userId ^ex:Member+/^ex:WritePermission ?parent } as ?hasWritePermissionToParent)
}

Expected: Both ?nameConflict and ?hasWritePermissionToParent should return false

Actual: Both return true


MarkLogic version: 11.0.2

This is also seen in MarkLogic v10


Is there anything wrong with the query ? Is any DB setting affecting the results ?


Update

MarkLogic confirms this is a bug. However the workaround select * too doesn't work and is highly inconsistent.

Scenario is changed a little bit, three more triples describing read permission are added:

Data:

prefix ex: <http://example.com/ns#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

insert data {
  ex:ID0 rdfs:label "Root" .
  ex:ID0 rdf:type ex:Folder .
  ex:ID0 ex:ReadPermission ex:GROUP1 .
  ex:ID0 ex:WritePermission ex:GROUP1 . 
  ex:ID1 rdfs:label "File1" .
  ex:ID1 rdf:type ex:File .
  ex:ID1 ex:Parent ex:ID0 .
  ex:ID1 ex:ReadPermission ex:GROUP2 .
  ex:ID1 ex:WritePermission ex:GROUP2 . 
  ex:ID2 rdfs:label "File2" .
  ex:ID2 rdf:type ex:File .
  ex:ID2 ex:Parent ex:ID0 .
  ex:ID2 ex:ReadPermission ex:GROUP2 .
  ex:ID2 ex:WritePermission ex:GROUP2 . 
  ex:ID3 rdfs:label "File3" .
  ex:ID3 rdf:type ex:File .
  ex:ID3 ex:Parent ex:ID0 .
  ex:ID3 ex:ReadPermission ex:GROUP2 .
  ex:ID3 ex:WritePermission ex:GROUP2 .
  ex:GROUP1 rdf:type ex:Group .
  ex:GROUP1 rdfs:label "Admin" .
  ex:GROUP1 ex:Member ex:USER1 .
  ex:GROUP2 rdf:type ex:Group .
  ex:GROUP2 rdfs:label "Users" .
  ex:GROUP2 ex:Member ex:USER2 .
  ex:USER1 rdf:type ex:User .
  ex:USER1 rdfs:label "User1" .
  ex:USER2 rdf:type ex:User .
  ex:USER2 rdfs:label "User2" .
}

Query:

prefix ex: <http://example.com/ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select *
where { 
  bind(ex:ID0 as ?id)

  ex:USER1 ^ex:Member+ ?groups .

  bind(exists{?id ex:ReadPermission ?groups} as ?hasReadPermission)
  bind(exists{?id ex:Source/ex:ReadPermission ?groups ; ex:Destination/ex:ReadPermission ?groups .} as ?linkHasReadPermission)
}

Expected results:

?id User Expected ?hasReadPermission
ID0 ex:USER1 true
ID0 ex:USER2 false
ID1/ID2/ID3 ex:USER1 false
ID1/ID2/ID3 ex:USER2 true

For the first row of values, at first it looks like it returns expected results. However when you try all combinations presented in the table above at some point you'll get an incorrect result, hence the inconsistency.

Upvotes: 3

Views: 576

Answers (1)

Florent Georges
Florent Georges

Reputation: 2327

Interestingly, replacing select ?nameConflict ?hasWritePermissionToParent by select * returns the right answer. Maybe you can use that as a workaround.

But this looks like a bug to me. You should report it. If you need help for that, I can help you, look at my profile for other ways to contact me directly.

Upvotes: 2

Related Questions