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

Parse update queries #1354

Merged
merged 17 commits into from
Jun 5, 2024
3 changes: 2 additions & 1 deletion src/parser/Triples.h → src/parser/SparqlTriple.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2024, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Julian Mundhahs ([email protected])
// Authors: Björn Buchhold ([email protected])
// Johannes Kalmbach <[email protected]>

#pragma once

Expand Down
6 changes: 3 additions & 3 deletions src/parser/UpdateClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#pragma once

#include "parser/SelectClause.h"
#include "parser/Triples.h"
#include "parser/SparqlTriple.h"
#include "parser/data/Types.h"

namespace parsedQuery {
Expand All @@ -14,8 +14,8 @@
std::vector<SparqlTripleSimple> toDelete_;

UpdateClause() = default;
explicit UpdateClause(std::vector<SparqlTripleSimple> toInsert,
std::vector<SparqlTripleSimple> toDelete)
UpdateClause(std::vector<SparqlTripleSimple> toInsert,
std::vector<SparqlTripleSimple> toDelete)
: toInsert_{std::move(toInsert)}, toDelete_{std::move(toDelete)} {}

Check warning on line 19 in src/parser/UpdateClause.h

View check run for this annotation

Codecov / codecov/patch

src/parser/UpdateClause.h#L19

Added line #L19 was not covered by tests
};
} // namespace parsedQuery
69 changes: 46 additions & 23 deletions src/parser/sparqlParser/SparqlQleverVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,8 @@
visit(ctx->prologue());

if (ctx->update()) {
reportNotSupported(ctx->update(),
"Multiple updates in one query are not supported.");
reportNotSupported(ctx->update(), "Multiple updates in one query are");
}

Check warning on line 334 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L333-L334

Added lines #L333 - L334 were not covered by tests
return visit(ctx->update1());
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}

Expand All @@ -342,56 +341,64 @@
return visit(ctx->modify());
}

// TODO: updates can be chained; think about how to enable this

parsedQuery_._clause = parsedQuery::UpdateClause();

if (ctx->insertData()) {
parsedQuery_.updateClause().toInsert_ = visit(ctx->insertData());
} else if (ctx->deleteData()) {
parsedQuery_.updateClause().toDelete_ = visit(ctx->deleteData());
} else if (ctx->deleteWhere()) {
auto [toDelete, pattern] = visit(ctx->deleteWhere());
parsedQuery_.updateClause().toDelete_ = std::move(toDelete);
parsedQuery_._rootGraphPattern = std::move(pattern);

Check warning on line 355 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L353-L355

Added lines #L353 - L355 were not covered by tests
} else if (ctx->modify()) {
// updates the internal state of `parsedQuery_`
visit(ctx->modify());
} else {
visitAlternative<void>(ctx->load(), ctx->clear(), ctx->drop(), ctx->add(),
ctx->move(), ctx->copy(), ctx->create(),
ctx->deleteWhere());
ctx->move(), ctx->copy(), ctx->create());
AD_FAIL();
}

Check warning on line 363 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L358-L363

Added lines #L358 - L363 were not covered by tests

return parsedQuery_;
}

// ____________________________________________________________________________________
void Visitor::visit(Parser::LoadContext* ctx) {
reportNotSupported(ctx, "SPARQL 1.1 Update Load is not supported.");
reportNotSupported(ctx, "SPARQL 1.1 Update Load is");
}

Check warning on line 371 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L369-L371

Added lines #L369 - L371 were not covered by tests

// ____________________________________________________________________________________
void Visitor::visit(Parser::ClearContext* ctx) {
reportNotSupported(ctx, "SPARQL 1.1 Update Clear is not supported.");
reportNotSupported(ctx, "SPARQL 1.1 Update Clear is");
}

Check warning on line 376 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L374-L376

Added lines #L374 - L376 were not covered by tests
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

// ____________________________________________________________________________________
void Visitor::visit(Parser::DropContext* ctx) {
reportNotSupported(ctx, "SPARQL 1.1 Update Drop is not supported.");
reportNotSupported(ctx, "SPARQL 1.1 Update Drop is");
}

Check warning on line 381 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L379-L381

Added lines #L379 - L381 were not covered by tests
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

// ____________________________________________________________________________________
void Visitor::visit(Parser::CreateContext* ctx) {
reportNotSupported(ctx, "SPARQL 1.1 Update Create is not supported.");
reportNotSupported(ctx, "SPARQL 1.1 Update Create is");
}

Check warning on line 386 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L384-L386

Added lines #L384 - L386 were not covered by tests

// ____________________________________________________________________________________
void Visitor::visit(Parser::AddContext* ctx) {
reportNotSupported(ctx, "SPARQL 1.1 Update Add is not supported.");
reportNotSupported(ctx, "SPARQL 1.1 Update Add is");
}

Check warning on line 391 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L389-L391

Added lines #L389 - L391 were not covered by tests

// ____________________________________________________________________________________
void Visitor::visit(Parser::MoveContext* ctx) {
reportNotSupported(ctx, "SPARQL 1.1 Update Move is not supported.");
reportNotSupported(ctx, "SPARQL 1.1 Update Move is");
}

Check warning on line 396 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L394-L396

Added lines #L394 - L396 were not covered by tests

// ____________________________________________________________________________________
void Visitor::visit(Parser::CopyContext* ctx) {
reportNotSupported(ctx, "SPARQL 1.1 Update Copy is not supported.");
reportNotSupported(ctx, "SPARQL 1.1 Update Copy is");
}

Check warning on line 401 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L399-L401

Added lines #L399 - L401 were not covered by tests

// ____________________________________________________________________________________
vector<SparqlTripleSimple> Visitor::visit(Parser::InsertDataContext* ctx) {
Expand All @@ -404,23 +411,40 @@
}

// ____________________________________________________________________________________
void Visitor::visit(Parser::DeleteWhereContext* ctx) {
// DeleteData only deletes the specified triples. DeleteWhere matches the
// given pattern and then deletes the matched triples. This is a shortcut for
// a modify query.
reportNotSupported(ctx, "SPARQL 1.1 Update DeleteWhere is not supported.");
std::pair<vector<SparqlTripleSimple>, ParsedQuery::GraphPattern> Visitor::visit(
Parser::DeleteWhereContext* ctx) {
auto triples = visit(ctx->quadPattern());
auto transformTriple =
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
[&ctx](const SparqlTripleSimple& triple) -> SparqlTriple {

Check warning on line 418 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L415-L418

Added lines #L415 - L418 were not covered by tests
if (triple.p_.isVariable()) {
return {triple.s_, PropertyPath::fromVariable(triple.p_.getVariable()),
triple.o_};

Check warning on line 421 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L420-L421

Added lines #L420 - L421 were not covered by tests
} else if (triple.p_.isIri()) {
return {
triple.s_,
PropertyPath::fromIri(triple.p_.getIri().toStringRepresentation()),
triple.o_};
} else {
reportError(ctx, "Predicate must a PropertyPath");
}
};
GraphPattern pattern;
pattern._graphPatterns.emplace_back(
BasicGraphPattern{ad_utility::transform(triples, transformTriple)});

Check warning on line 433 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L423-L433

Added lines #L423 - L433 were not covered by tests

return {std::move(triples), std::move(pattern)};
}

Check warning on line 436 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L435-L436

Added lines #L435 - L436 were not covered by tests
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

// ____________________________________________________________________________________
ParsedQuery Visitor::visit(Parser::ModifyContext* ctx) {
if (ctx->iri()) {
// Could also be default; disallow completely for now.
reportNotSupported(ctx->iri(), "Named graphs are not supported.");
reportNotSupported(ctx->iri(), "Named graphs are");
}

Check warning on line 443 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L442-L443

Added lines #L442 - L443 were not covered by tests
if (!ctx->usingClause().empty()) {
reportNotSupported(ctx->usingClause(0),
"Using is not supported in Update/Insert.");
"USING inside an DELETE or INSERT is");
}

Check warning on line 447 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L445-L447

Added lines #L445 - L447 were not covered by tests

parsedQuery_._rootGraphPattern = visit(ctx->groupGraphPattern());

Expand Down Expand Up @@ -455,9 +479,9 @@
auto quads = visit(ctx->quads());
auto checkAndReportVar = [&ctx](const TripleComponent& term) {
if (term.isVariable()) {
reportError(ctx->quads(), "Variables (" + term.getVariable().name() +
") are not allowed here.");
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}

Check warning on line 484 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L482-L484

Added lines #L482 - L484 were not covered by tests
};

for (const auto& quad : quads) {
Expand All @@ -473,14 +497,14 @@
vector<SparqlTripleSimple> Visitor::visit(Parser::QuadsContext* ctx) {
if (!ctx->quadsNotTriples().empty()) {
// Could also be default; disallow completely for now.
reportNotSupported(ctx->quadsNotTriples(0),
"Named graphs are not supported.");
reportNotSupported(ctx->quadsNotTriples(0), "Named graphs are");
}

Check warning on line 501 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L500-L501

Added lines #L500 - L501 were not covered by tests

AD_CORRECTNESS_CHECK(ctx->triplesTemplate().size() == 1);

auto convertAndRegisterTriple =
[this](const std::array<GraphTerm, 3>& triple) -> SparqlTripleSimple {
// TODO:
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
registerIfVariable(triple[0]);
registerIfVariable(triple[1]);
registerIfVariable(triple[2]);
Expand All @@ -489,9 +513,8 @@
visitGraphTerm(triple[2])};
};

std::vector<SparqlTripleSimple> triples = {ad_utility::transform(
visit(ctx->triplesTemplate(0)), convertAndRegisterTriple)};
return triples;
return ad_utility::transform(visit(ctx->triplesTemplate(0)),
convertAndRegisterTriple);
}

// ____________________________________________________________________________________
Expand Down Expand Up @@ -2328,11 +2351,11 @@
if constexpr (std::is_same_v<T, Variable>) {
return element;
} else if constexpr (std::is_same_v<T, Literal> || std::is_same_v<T, Iri>) {
return TurtleStringParser<TokenizerCtre>::parseTripleObject(
element.toSparql());
} else {
return element.toSparql();
}

Check warning on line 2358 in src/parser/sparqlParser/SparqlQleverVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/parser/sparqlParser/SparqlQleverVisitor.cpp#L2354-L2358

Added lines #L2354 - L2358 were not covered by tests
});
}

Expand Down
6 changes: 5 additions & 1 deletion src/parser/sparqlParser/SparqlQleverVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ class SparqlQleverVisitor {

vector<SparqlTripleSimple> visit(Parser::DeleteDataContext* ctx);

void visit(Parser::DeleteWhereContext* ctx);
std::pair<vector<SparqlTripleSimple>, ParsedQuery::GraphPattern> visit(
Parser::DeleteWhereContext* ctx);

ParsedQuery visit(Parser::ModifyContext* ctx);

Expand Down Expand Up @@ -625,6 +626,9 @@ class SparqlQleverVisitor {
void setMatchingWordAndScoreVisibleIfPresent(
auto* ctx, const TripleWithPropertyPath& triple);

// Constructs a TripleComponent from a GraphTerm.
static TripleComponent visitGraphTerm(const GraphTerm& graphTerm);
// If argument is a variant that contains a Variable register that Variable as
// visible in the current scope.
void registerIfVariable(const auto& variant);
};
4 changes: 2 additions & 2 deletions test/SparqlAntlrParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1666,8 +1666,8 @@ TEST(SparqlParser, UpdateQuery) {
m::UpdateQuery({}, {{Iri("<a>"), Iri("<b>"), Iri("<c>")}},
m::GraphPattern()));
expectUpdate(
"INSERT DATA { \"foo:bar\" <b> <c> }",
m::UpdateQuery({}, {{Literal("\"foo:bar\""), Iri("<b>"), Iri("<c>")}},
"INSERT DATA { <a> <b> \"foo:bar\" }",
m::UpdateQuery({}, {{Iri("<a>"), Iri("<b>"), Literal("\"foo:bar\"")}},
m::GraphPattern()));
expectUpdate("DELETE DATA { <a> <b> <c> }",
m::UpdateQuery({{Iri("<a>"), Iri("<b>"), Iri("<c>")}}, {},
Expand Down
10 changes: 5 additions & 5 deletions test/SparqlAntlrParserTestHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -824,9 +824,9 @@ inline auto ConstructQuery(const std::vector<std::array<GraphTerm, 3>>& elems,
-> Matcher<const ParsedQuery&> {
return testing::AllOf(
AD_PROPERTY(ParsedQuery, hasConstructClause, testing::IsTrue()),
AD_PROPERTY(
ParsedQuery, constructClause,
AD_FIELD(parsedQuery::ConstructClause, triples_, testing::Eq(elems))),
AD_PROPERTY(ParsedQuery, constructClause,
AD_FIELD(parsedQuery::ConstructClause, triples_,
testing::ElementsAreArray(elems))),
RootGraphPattern(m));
}

Expand All @@ -845,10 +845,10 @@ inline auto UpdateQuery =
AD_PROPERTY(ParsedQuery, hasUpdateClause, testing::IsTrue()),
AD_PROPERTY(ParsedQuery, updateClause,
AD_FIELD(parsedQuery::UpdateClause, toDelete_,
testing::Eq(toDelete))),
testing::ElementsAreArray(toDelete))),
AD_PROPERTY(ParsedQuery, updateClause,
AD_FIELD(parsedQuery::UpdateClause, toInsert_,
testing::Eq(toInsert))),
testing::ElementsAreArray(toInsert))),
RootGraphPattern(graphPatternMatcher));
};

Expand Down
Loading