Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import org.gradle.api.tasks.compile.JavaCompile
import java.time.LocalDate
import java.time.format.DateTimeFormatter

Expand Down Expand Up @@ -54,7 +55,7 @@ javacc {
sourceSets {
main {
java {
setSrcDirs(listOf("src/main/java", javaccGeneratedDir, antlrPackageDir))
setSrcDirs(listOf("src/main/java", javaccGeneratedDir, antlrGeneratedDir))
}
}
}
Expand Down Expand Up @@ -306,11 +307,15 @@ tasks.named("compileJava") {
dependsOn("generateGrammarSource", "javaccSparqlCorese")
}

tasks.named<JavaCompile>("compileJava") {
source(antlrPackageDir)
}

// Ensure sources JAR includes generated sources and depends on code generation
tasks.named<Jar>("sourcesJar") {
dependsOn("generateGrammarSource", "javaccSparqlCorese")
from(javaccGeneratedDir)
from(antlrPackageDir)
from(antlrGeneratedDir)
includeEmptyDirs = false
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fr.inria.corese.core.next.query.api.exception;

/**
* Thrown when a syntactically valid query uses a feature not implemented by the current next pipeline.
*/
@SuppressWarnings("java:S110")
public class UnsupportedQueryFeatureException extends QueryEvaluationException {

public UnsupportedQueryFeatureException(String message) {
super(message);
}

public UnsupportedQueryFeatureException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ public void enterBgp() {
bgpStack.push(new ArrayList<>());
}

public boolean hasCurrentBgp() {
return !bgpStack.isEmpty();
}

/**
* Exit a TriplesBlock -> finalize into BgpAst and attach it to the current group.
* Empty triples blocks produce no pattern.
Expand Down Expand Up @@ -1180,9 +1184,9 @@ public TermAst termFromAdditive(SparqlParser.AdditiveExpressionContext ctx) {
case SparqlParser.MultiplicativeExpressionContext multiplicativeExpressionContext ->
termFromMultiplicative(multiplicativeExpressionContext);
case SparqlParser.NumericLiteralPositiveContext numericLiteralPositiveContext ->
(ExprAst) termFromNumericLiteralPositive(numericLiteralPositiveContext);
termFromNumericLiteralPositive(numericLiteralPositiveContext);
case SparqlParser.NumericLiteralNegativeContext numericLiteralNegativeContext ->
(ExprAst) termFromNumericLiteralNegative(numericLiteralNegativeContext);
termFromNumericLiteralNegative(numericLiteralNegativeContext);
case null, default ->
throw new QueryEvaluationException(
"Unexpected left hand termFromExpression in additive termFromExpression "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
import java.util.List;

/**
* SPARQL listener multiplexer: forwards to delegates only the events needed for
* triple patterns (?s ?p ?o) and BGPs (GroupGraphPattern, TriplesBlock, TriplesSameSubject).
* Additional rules can be added later if needed.
* SPARQL listener multiplexer: forwards the grammar events supported by the
* next AST builders to their feature-specific delegates.
*/
public final class SparqlListener extends SparqlParserBaseListener {

Expand Down Expand Up @@ -79,6 +78,16 @@ public void exitLoad(SparqlParser.LoadContext ctx) {
for (var d : delegates) d.exitLoad(ctx);
}

@Override
public void exitInsertData(SparqlParser.InsertDataContext ctx) {
for (var d : delegates) d.exitInsertData(ctx);
}

@Override
public void exitDeleteData(SparqlParser.DeleteDataContext ctx) {
for (var d : delegates) d.exitDeleteData(ctx);
}

@Override
public void enterClear(SparqlParser.ClearContext ctx) {
for (var d : delegates) d.enterClear(ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ private QueryAst buildAst(ParseTree tree, SparqlParserOptions options) {
SparqlListener updateListener = new SparqlListener(List.of(
new ClearRequestFeature(updateBuilder),
new CreateRequestFeature(updateBuilder),
new DeleteDataRequestFeature(updateBuilder),
new InsertDataRequestFeature(updateBuilder),
new LoadRequestFeature(updateBuilder),
new BgpFeature(updateBuilder),
new BindFeature(updateBuilder),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import fr.inria.corese.core.next.impl.parser.antlr.SparqlParser;
import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException;
import fr.inria.corese.core.next.query.api.exception.UnsupportedQueryFeatureException;
import fr.inria.corese.core.next.query.impl.sparql.ast.*;

import java.util.ArrayList;
Expand Down Expand Up @@ -67,6 +68,62 @@ public CreateRequestAst createToAst(SparqlParser.CreateContext ctx) {
throw new QueryEvaluationException("No target graph reference found in CREATE query");
}

public InsertDataRequestAst insertDataToAst(SparqlParser.InsertDataContext ctx) {
return new InsertDataRequestAst(triplesFromQuadData(ctx.quadData()));
}

public DeleteDataRequestAst deleteDataToAst(SparqlParser.DeleteDataContext ctx) {
return new DeleteDataRequestAst(triplesFromQuadData(ctx.quadData()));
}

private List<TriplePatternAst> triplesFromQuadData(SparqlParser.QuadDataContext ctx) {
if (ctx == null || ctx.quads() == null) {
return List.of();
}
return triplesFromQuads(ctx.quads());
}

private List<TriplePatternAst> triplesFromQuads(SparqlParser.QuadsContext ctx) {
if (ctx.quadsNotTriples() != null && !ctx.quadsNotTriples().isEmpty()) {
throw new UnsupportedQueryFeatureException(
"GRAPH blocks in INSERT DATA / DELETE DATA are not supported yet by the next pipeline");
}

List<TriplePatternAst> triples = new ArrayList<>();
if (ctx.triplesTemplate() != null) {
for (SparqlParser.TriplesTemplateContext template : ctx.triplesTemplate()) {
collectTriplesTemplate(template, triples);
}
}
return List.copyOf(triples);
}

private void collectTriplesTemplate(SparqlParser.TriplesTemplateContext ctx, List<TriplePatternAst> triples) {
if (ctx == null) {
return;
}
if (ctx.triplesSameSubject() != null) {
collectTriplesSameSubject(ctx.triplesSameSubject(), triples);
}
if (ctx.triplesTemplate() != null) {
collectTriplesTemplate(ctx.triplesTemplate(), triples);
}
}

private void collectTriplesSameSubject(SparqlParser.TriplesSameSubjectContext ctx, List<TriplePatternAst> triples) {
if (ctx.varOrTerm() == null || ctx.propertyListNotEmpty() == null) {
return;
}
TermAst subject = termFromVarOrTerm(ctx.varOrTerm());
var propertyList = ctx.propertyListNotEmpty();
for (int verbIndex = 0; verbIndex < propertyList.verb().size(); verbIndex++) {
TermAst predicate = termFromVerb(propertyList.verb(verbIndex));
for (TermAst object : termListFromObjectList(propertyList.objectList(verbIndex))) {
triples.add(new TriplePatternAst(subject, predicate, object));
}
}
}

public void addRequest(UpdateRequestUnitAst ast) {
this.updateRequestAst.add(ast);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ public void exitTriplesSameSubject(SparqlParser.TriplesSameSubjectContext ctx) {
if (ctx.getParent() instanceof SparqlParser.ConstructTriplesContext) {
return;
}
if (!builder().hasCurrentBgp()) {
return;
}
if (ctx.varOrTerm() == null || ctx.propertyListNotEmpty() == null) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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.SparqlUpdateAstBuilder;

/**
* AST feature listener for the minimal {@code DELETE DATA} update operation.
*/
public class DeleteDataRequestFeature extends AbstractSparqlRequestFeature {

public DeleteDataRequestFeature(SparqlUpdateAstBuilder builder) {
super(builder);
}

@Override
public void exitDeleteData(SparqlParser.DeleteDataContext ctx) {
updateBuilder().addRequest(updateBuilder().deleteDataToAst(ctx));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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.SparqlUpdateAstBuilder;

/**
* AST feature listener for the minimal {@code INSERT DATA} update operation.
*/
public class InsertDataRequestFeature extends AbstractSparqlRequestFeature {

public InsertDataRequestFeature(SparqlUpdateAstBuilder builder) {
super(builder);
}

@Override
public void exitInsertData(SparqlParser.InsertDataContext ctx) {
updateBuilder().addRequest(updateBuilder().insertDataToAst(ctx));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package fr.inria.corese.core.next.query.impl.sparql.ast;

import fr.inria.corese.core.next.query.impl.parser.semantic.support.AstVisitor;

import java.util.List;

/**
* Minimal AST representation of {@code DELETE DATA} for concrete triples.
*/
public record DeleteDataRequestAst(List<TriplePatternAst> triples) implements UpdateRequestUnitAst {

public DeleteDataRequestAst {
triples = triples != null ? List.copyOf(triples) : List.of();
}

@Override
public void accept(AstVisitor visitor) {
visitor.visit(this);
triples.forEach(triple -> triple.accept(visitor));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package fr.inria.corese.core.next.query.impl.sparql.ast;

import fr.inria.corese.core.next.query.impl.parser.semantic.support.AstVisitor;

import java.util.List;

/**
* Minimal AST representation of {@code INSERT DATA} for concrete triples.
*/
public record InsertDataRequestAst(List<TriplePatternAst> triples) implements UpdateRequestUnitAst {

public InsertDataRequestAst {
triples = triples != null ? List.copyOf(triples) : List.of();
}

@Override
public void accept(AstVisitor visitor) {
visitor.visit(this);
triples.forEach(triple -> triple.accept(visitor));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
/**
* Root interface for all operations related to the SPARQL Update operations listed in <a href="https://www.w3.org/TR/sparql11-update/">SPARQL 1.1 Update</a>.
*/
public sealed interface UpdateRequestUnitAst extends VisitableAst permits LoadRequestAst, ClearRequestAst, CreateRequestAst {
public sealed interface UpdateRequestUnitAst extends VisitableAst permits LoadRequestAst, ClearRequestAst, CreateRequestAst, InsertDataRequestAst, DeleteDataRequestAst {
}
Loading