Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GROUP_CONCAT with OPTIONAL returns 'None' #1467

Closed
KonradHoeffner opened this issue Nov 16, 2021 · 5 comments · Fixed by #1887
Closed

GROUP_CONCAT with OPTIONAL returns 'None' #1467

KonradHoeffner opened this issue Nov 16, 2021 · 5 comments · Fixed by #1887
Assignees
Labels

Comments

@KonradHoeffner
Copy link

KonradHoeffner commented Nov 16, 2021

A query such as the following on https://hitontology.eu/sparql returns empty strings for nonexisting GROUP_CONCAT results using Virtuoso:

PREFIX dce: <http://purl.org/dc/elements/1.1/>
PREFIX hito: <http://hitontology.eu/ontology/>
SELECT
?classified
(GROUP_CONCAT(DISTINCT(STR(?dce_source));separator="|") AS ?dce_sources)
{
 ?classified a hito:FeatureClassified.
 OPTIONAL {?classified dce:source ?dce_source.}
}

However when querying an RDFLib graph, I get rdflib.term.Literal('None') values in my result set. Is that intended?

@ghost ghost added the SPARQL label Dec 23, 2021
@aucampia
Copy link
Member

aucampia commented May 3, 2022

@KonradHoeffner could you give some more detail on this? What was the actual graph you were querying or were you using a remote store?

@KonradHoeffner
Copy link
Author

KonradHoeffner commented May 4, 2022

I am using the default graph with a remote SPARQL endpoint. Here is a complete minimal example of the problem:

RDFLib Example Code

import rdflib
g = rdflib.Graph()
qres = g.query(
 """   
PREFIX dce: <http://purl.org/dc/elements/1.1/>
PREFIX hito: <http://hitontology.eu/ontology/>
                                                                                               
SELECT ?classified (GROUP_CONCAT(DISTINCT(STR(?dce_source));separator="|") AS ?dce_sources)
{                                                  
    SERVICE <https://hitontology.eu/sparql>
    {
        ?classified a hito:FeatureClassified.
        OPTIONAL {?classified dce:source ?dce_source.}
    }
}    
LIMIT 3    
"""    
)
for row in qres:
    print(row)  

RDFLib Output

$ python rdflibtest.py
(rdflib.term.URIRef('http://hitontology.eu/ontology/BbAdministrateTheMasterPatientIndexMpi'), rdflib.term.Literal('None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None|None'))
$ pip install rdflib
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: rdflib in /home/konrad/.local/lib/python3.10/site-packages (6.1.1)
Requirement already satisfied: setuptools in /usr/lib/python3.10/site-packages (from rdflib) (59.5.0)
Requirement already satisfied: isodate in /home/konrad/.local/lib/python3.10/site-packages (from rdflib) (0.6.1)
Requirement already satisfied: pyparsing in /usr/lib/python3.10/site-packages (from rdflib) (3.0.8)
Requirement already satisfied: six in /usr/lib/python3.10/site-packages (from isodate->rdflib) (1.16.0)

Manual Query on https://hitontology.eu/sparql

PREFIX dce: <http://purl.org/dc/elements/1.1/>
PREFIX hito: <http://hitontology.eu/ontology/>
                                                                                               
SELECT ?classified (GROUP_CONCAT(DISTINCT(STR(?dce_source));separator="|") AS ?dce_sources)
{                                                  
        ?classified a hito:FeatureClassified.
        OPTIONAL {?classified dce:source ?dce_source.}
}    
LIMIT 3  

Manual Query Result

classified dce_sources
http://hitontology.eu/ontology/EhrSfmPatientspecificMedicationDosingAndWarnings  
http://hitontology.eu/ontology/EhrSfmUserAccessSuccessfulSecurityAuditTrigger  
http://hitontology.eu/ontology/EhrSfmUserPermissionsAuthorizationSecurityAuditTrigger  

Comparison

RDFLib generates "None|None|None|..." but Virtuoso SPARQL generates an empty string as intended.

@aucampia
Copy link
Member

aucampia commented May 4, 2022

Thanks a bunch for the detailed info, very helpful, will see what I can do about it.

@aucampia aucampia self-assigned this May 4, 2022
@ghost
Copy link

ghost commented May 4, 2022

fwiw, adding a GROUP BY ?classified (as appearing in the Virtuoso optimized query), changes the number of None results to just three.

@aucampia
Copy link
Member

aucampia commented May 5, 2022

I can more or less reproduce this, but should GROUP_CONCAT not be accompanied with a GROUP BY clause? It seems Virtuoso is fine with no GROUP BY but Jena does not like it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants