-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The change introduces a check_query callable which runs an extensible compose pipeline of query checkers. Note regarding QueryParseException: This custom exception is intended to be a thin wrapper around a pyparsing ParseException that RDFLib raises. This avoids introducing pyparsing as a dependency just to be able to test against this exception. I feel like RDFLib should not raise a pyparsing exception but provide a thin wrapper itself. See RDFLib/rdflib#3057. The check_query function runs in SPARQLModelAdapter to enable fast failures on inapplicable queries. Note that this somewhat couples QueryConstructor to SPARQLModelAdapter; QueryConstructor should be marked private for this reason. Possible handling of queries with outer-level solution modifiers is discussed in issue #206. Closes #116. Closes #126.
- Loading branch information
Showing
5 changed files
with
101 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
"""Functionality for performing checks on SPARQL queries.""" | ||
|
||
import logging | ||
|
||
from rdfproxy.utils._exceptions import UnsupportedQueryException | ||
from rdfproxy.utils._types import ParsedSPARQL, _TQuery | ||
from rdfproxy.utils.utils import compose_left | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def _check_select_query(parsed_sparql: ParsedSPARQL) -> ParsedSPARQL: | ||
"""Check if a SPARQL query is a SELECT query. | ||
This is meant to run as a component in check_query. | ||
""" | ||
logger.debug("Running SELECT query check.") | ||
|
||
if parsed_sparql.parse_object.name != "SelectQuery": | ||
raise UnsupportedQueryException("Only SELECT queries are applicable.") | ||
return parsed_sparql | ||
|
||
|
||
def _check_solution_modifiers(parsed_sparql: ParsedSPARQL) -> ParsedSPARQL: | ||
"""Check if a SPARQL query has a solution modifier. | ||
This is meant to run as a component in check_query. | ||
""" | ||
logger.debug("Running solution modifier check.") | ||
|
||
def _has_modifier(): | ||
for mod_name in ["limitoffset", "groupby", "having", "orderby"]: | ||
if (mod := getattr(parsed_sparql.parse_object, mod_name)) is not None: | ||
return mod | ||
return False | ||
|
||
if mod := _has_modifier(): | ||
logger.critical("Detected solution modifier '%s' in outer query.", mod) | ||
raise UnsupportedQueryException( | ||
"Solution modifiers for top-level queries are currently not supported." | ||
) | ||
|
||
return parsed_sparql | ||
|
||
|
||
def check_query(query: _TQuery) -> _TQuery: | ||
"""Check a SPARQL query by running a compose pipeline of checks.""" | ||
logger.debug("Running query check pipeline on '%s'", query) | ||
parsed_sparql = ParsedSPARQL(query=query) | ||
|
||
result: ParsedSPARQL = compose_left( | ||
_check_select_query, | ||
_check_solution_modifiers, | ||
)(parsed_sparql) | ||
|
||
return result.data |