-
Notifications
You must be signed in to change notification settings - Fork 2
371 [SPARQL 1.1 Update] - Parser and AST : LOAD and CLEAR Query #452
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
base: feature/corese-next
Are you sure you want to change the base?
Changes from all commits
f64ff56
41d580b
7aa064b
b1cf7e6
69774e2
e98bf30
12a9589
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package fr.inria.corese.core.next.query.impl.parser.listener; | ||
|
|
||
| import fr.inria.corese.core.next.impl.parser.antlr.SparqlParser; | ||
| import fr.inria.corese.core.next.query.impl.parser.SparqlAstBuilder; | ||
|
|
||
| /** | ||
| * AST feature listener for CLEAR SPARQL update query | ||
| */ | ||
| public class ClearQueryFeature extends AbstractSparqlFeature { | ||
| public ClearQueryFeature(SparqlAstBuilder builder) { | ||
| super(builder); | ||
| } | ||
|
|
||
| @Override | ||
| public void exitClear(SparqlParser.ClearContext ctx) { | ||
| this.builder().exitClearQuery(); | ||
| this.builder().setSilentFlag(ctx.SILENT() != null); | ||
| if(ctx.graphRefAll() != null) { | ||
| this.builder().setTargetGraphIri(this.builder().graphRefFromGraphRefAll(ctx.graphRefAll())); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package fr.inria.corese.core.next.query.impl.parser.listener; | ||
|
|
||
| import fr.inria.corese.core.next.impl.parser.antlr.SparqlParser; | ||
| import fr.inria.corese.core.next.query.impl.parser.SparqlAstBuilder; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.IriAst; | ||
|
|
||
| /** | ||
| * AST feature listener for LOAD SPARQL update query | ||
| */ | ||
| public class LoadQueryFeature extends AbstractSparqlFeature { | ||
|
|
||
| public LoadQueryFeature(SparqlAstBuilder builder) { | ||
| super(builder); | ||
| } | ||
|
|
||
| public void exitLoad(SparqlParser.LoadContext ctx) { | ||
| this.builder().enterLoadQuery(); | ||
| this.builder().setSilentFlag(ctx.SILENT() != null); | ||
| if(ctx.iriRef() != null) { | ||
| this.builder().setSourceGraphIri((IriAst) this.builder().termFromIriRef(ctx.iriRef())); | ||
| } | ||
| if(ctx.graphRef() != null) { | ||
| this.builder().setTargetGraphIri((IriAst) this.builder().termFromGraphRef(ctx.graphRef())); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,10 +5,7 @@ | |
| import org.slf4j.Logger; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The import org.slf4j.Logger is never used |
||
| import org.slf4j.LoggerFactory; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this unused import 'org.slf4j.LoggerFactory'. |
||
|
|
||
| import java.util.HashSet; | ||
| import java.util.LinkedHashSet; | ||
| import java.util.List; | ||
| import java.util.Set; | ||
| import java.util.*; | ||
|
|
||
| /** | ||
| * Collects visible and referenced variables from the next SPARQL AST. | ||
|
|
@@ -26,8 +23,13 @@ public final class VariableScopeAnalyzer { | |
| * @return the set of visible variable names, without {@code ?} or {@code $} in the patterns used for the resolution of the query | ||
| */ | ||
| public Set<String> collectVisibleVariables(QueryAst query) { | ||
| Set<String> visibleVariables = collectVisibleVariables(query.whereClause()); | ||
| visibleVariables.addAll(collectVisibleVariables(query.valuesClause())); | ||
| Set<String> visibleVariables = new TreeSet<>(); | ||
| if(query instanceof WhereClauseQueryAst whereClauseQueryAst) { | ||
| visibleVariables.addAll(collectVisibleVariables(whereClauseQueryAst.whereClause())); | ||
| } | ||
| if(query instanceof SparqlQueryAst sparqlQueryAst) { | ||
| visibleVariables.addAll(collectVisibleVariables(sparqlQueryAst.valuesClause())); | ||
| } | ||
| return visibleVariables; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,9 @@ public enum QUERY_TYPE { | |
| DESCRIBE, | ||
| SELECT, | ||
|
|
||
| LOAD, | ||
| CLEAR, | ||
|
|
||
| UNDEFINED | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| /** | ||
| * Represents the CLEAR queries as defined in the <a href="https://www.w3.org/TR/2013/REC-sparql11-update-20130321/#clear">SPARQL 1.1 recommendation<a/>. | ||
| * @param graphRef targeted graph to be cleared | ||
| * @param silent Determine if the resolution of the query must be resolved silently or not. | ||
| */ | ||
| public record ClearQueryAst(GraphRefAst graphRef, boolean silent) implements UpdateQueryAst { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException; | ||
|
|
||
| import java.util.ArrayList; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this unused import 'java.util.ArrayList'. |
||
| import java.util.List; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this unused import 'java.util.List'. |
||
|
|
||
| public record GraphRefAst(IriAst graph, boolean named, boolean all, boolean defaultGraph) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This constructor allows invalid mixed states such as an explicit graph together with named, all, or defaultGraph. |
||
| public GraphRefAst { | ||
| if(graph == null && !named && !all && !defaultGraph) { | ||
| throw new QueryEvaluationException("Graph reference does not actually reference any graph"); | ||
| } | ||
| if(named && all) { | ||
| throw new QueryEvaluationException("Cannot have a Graph reference that is ALL and NAMED at the same time"); | ||
| } | ||
| if(named && defaultGraph) { | ||
| throw new QueryEvaluationException("Cannot have a Graph reference that is NAMED and DEFAULT at the same time"); | ||
| } | ||
| if(defaultGraph && all) { | ||
| throw new QueryEvaluationException("Cannot have a Graph reference that is ALL and DEFAULT at the same time"); | ||
| } | ||
| } | ||
|
|
||
| public GraphRefAst(IriAst graph) { | ||
| this(graph, false, false, false); | ||
| } | ||
|
|
||
| public GraphRefAst(boolean named, boolean all, boolean defaultGraph) { | ||
| this(null, named, all, defaultGraph); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| /** | ||
| * Constructor functions for Graph references | ||
| */ | ||
| public class GraphRefAsts { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a private constructor to hide the implicit public one. |
||
|
|
||
| public static GraphRefAst named() { | ||
| return new GraphRefAst(true, false, false); | ||
| } | ||
|
|
||
| public static GraphRefAst all() { | ||
| return new GraphRefAst(false, true, false); | ||
| } | ||
|
|
||
| public static GraphRefAst defaultGraph() { | ||
| return new GraphRefAst(false, false, true); | ||
| } | ||
|
|
||
| public static GraphRefAst graph(IriAst graphIri) { | ||
| return new GraphRefAst(graphIri); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException; | ||
|
|
||
| import java.util.HashSet; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this unused import 'java.util.HashSet'. |
||
| import java.util.Set; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this unused import 'java.util.Set'. |
||
|
|
||
| /** | ||
| * Represents the LOAD queries as defined in the <a href="https://www.w3.org/TR/2013/REC-sparql11-update-20130321/#load">SPARQL 1.1 recommendation<a/>. | ||
| * @param fromClause From clause, set of graphs IRIs | ||
| * @param toClause To clause. Set of Graph IRIs | ||
| * @param silent Determine if the resolution of the query must be resolved silently or not. | ||
| */ | ||
| public record LoadQueryAst(GraphRefAst fromClause, GraphRefAst toClause, boolean silent) implements UpdateQueryAst { | ||
| public LoadQueryAst { | ||
| if(fromClause == null) { | ||
| throw new QueryEvaluationException("Load query must have at least an URI to load from"); | ||
| } | ||
| } | ||
|
|
||
| public LoadQueryAst(GraphRefAst fromClause, GraphRefAst toClause) { | ||
| this(fromClause, toClause, false); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| /** | ||
| * Represents queries that can be prefixed with a prologue declaration (i.e. Select, Insert, etc.) | ||
| */ | ||
| public sealed interface PrologueQueryAst permits SparqlQueryAst { | ||
| QueryPrologueAst prologue(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,4 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| /** | ||
| * Minimal SPARQL query AST (SELECT, ASK, CONSTRUCT, DESCRIBE). | ||
| * Holds the WHERE clause as a group graph pattern; query-specific projection/template can be added later. | ||
| */ | ||
| public sealed interface QueryAst permits AskQueryAst, ConstructQueryAst, DescribeQueryAst, SelectQueryAst { | ||
| DatasetClauseAst datasetClause(); | ||
| GroupGraphPatternAst whereClause(); | ||
| QueryPrologueAst prologue(); | ||
| ValuesAst valuesClause(); | ||
| } | ||
| public sealed interface QueryAst permits SparqlQueryAst, UpdateQueryAst { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| /** | ||
| * Minimal SPARQL query AST (SELECT, ASK, CONSTRUCT, DESCRIBE). | ||
| * Holds the WHERE clause as a group graph pattern; query-specific projection/template can be added later. | ||
| */ | ||
| public sealed interface SparqlQueryAst extends QueryAst, PrologueQueryAst, WhereClauseQueryAst permits AskQueryAst, ConstructQueryAst, DescribeQueryAst, SelectQueryAst { | ||
| DatasetClauseAst datasetClause(); | ||
| ValuesAst valuesClause(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| /** | ||
| * Root interface for all queries related to the SPARQL Update queries listed in <a href="https://www.w3.org/TR/sparql11-update/">SPARQL 1.1 Update</>. | ||
| */ | ||
| public sealed interface UpdateQueryAst extends QueryAst permits LoadQueryAst, ClearQueryAst { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updates can start with Example: PREFIX ex: <http://example.org/>
LOAD ex:data
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Test
void updateShouldKeepPrologue() {
QueryParser parser = newParserDefault();
String query = """
PREFIX ex: <http://example.org/>
LOAD ex:data
""";
QueryAst queryAst = parser.parse(query);
UpdateRequestAst update = assertInstanceOf(UpdateRequestAst.class, queryAst);
assertEquals(1, update.operations().size());
assertTrue(update.prologue().prefixDeclarations().stream()
.anyMatch(prefixDecl ->
prefixDecl.prefix().equals("ex")
&& prefixDecl.namespace().raw().equals("http://example.org/")));
assertInstanceOf(LoadQueryAst.class, update.operations().get(0));
} |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package fr.inria.corese.core.next.query.impl.sparql.ast; | ||
|
|
||
| /** | ||
| * Represents the AST elements of a query that has a WHERE clause (SELECT, CONSTRUCT, INSERT, DELETE, etc.) | ||
| */ | ||
| public sealed interface WhereClauseQueryAst permits SparqlQueryAst { | ||
| GroupGraphPatternAst whereClause(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the "@OverRide" annotation above this method signature