Skip to content

Commit c3a9a7d

Browse files
committed
Added some more tests.
Signed-off-by: Johannes Kalmbach <johannes.kalmbach@gmail.com>
1 parent 91e5802 commit c3a9a7d

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

src/parser/sparqlParser/SparqlQleverVisitor.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ ParsedQuery Visitor::visit(Parser::ConstructQueryContext* ctx) {
268268
ParsedQuery query;
269269
query.datasetClauses_ = parsedQuery::DatasetClauses::fromClauses(
270270
visitVector(ctx->datasetClause()));
271+
activeDatasetClauses_ = query.datasetClauses_;
271272
if (ctx->constructTemplate()) {
272273
query._clause = visit(ctx->constructTemplate())
273274
.value_or(parsedQuery::ConstructClause{});
@@ -303,9 +304,9 @@ ParsedQuery Visitor::visit(Parser::DescribeQueryContext* ctx) {
303304
}
304305

305306
// Parse the FROM and FROM NAMED clauses.
306-
auto datasetClauses = parsedQuery::DatasetClauses::fromClauses(
307+
activeDatasetClauses_ = parsedQuery::DatasetClauses::fromClauses(
307308
visitVector(ctx->datasetClause()));
308-
describeClause.datasetClauses_ = datasetClauses;
309+
describeClause.datasetClauses_ = activeDatasetClauses_;
309310

310311
// Parse the WHERE clause and construct a SELECT query from it. For `DESCRIBE
311312
// *`, add each visible variable as a resource to describe.
@@ -336,7 +337,7 @@ ParsedQuery Visitor::visit(Parser::DescribeQueryContext* ctx) {
336337
parsedQuery_.addSolutionModifiers(visit(ctx->solutionModifier()));
337338
parsedQuery_._rootGraphPattern._graphPatterns.emplace_back(
338339
std::move(describeClause));
339-
parsedQuery_.datasetClauses_ = datasetClauses;
340+
parsedQuery_.datasetClauses_ = activeDatasetClauses_;
340341
auto constructClause = ParsedQuery::ConstructClause{};
341342
using G = GraphTerm;
342343
using V = Variable;
@@ -352,6 +353,7 @@ ParsedQuery Visitor::visit(Parser::AskQueryContext* ctx) {
352353
parsedQuery_._clause = ParsedQuery::AskClause{};
353354
parsedQuery_.datasetClauses_ = parsedQuery::DatasetClauses::fromClauses(
354355
visitVector(ctx->datasetClause()));
356+
activeDatasetClauses_ = parsedQuery_.datasetClauses_;
355357
visitWhereClause(ctx->whereClause(), parsedQuery_);
356358
// NOTE: It can make sense to have solution modifiers with an ASK query, for
357359
// example, a GROUP BY with a HAVING.
@@ -595,6 +597,8 @@ ParsedQuery Visitor::visit(Parser::ModifyContext* ctx) {
595597
};
596598
AD_CORRECTNESS_CHECK(visibleVariables_.empty());
597599
auto graphPattern = visit(ctx->groupGraphPattern());
600+
parsedQuery_.datasetClauses_ =
601+
parsedQuery::DatasetClauses::fromClauses(visitVector(ctx->usingClause()));
598602
parsedQuery_._rootGraphPattern = std::move(graphPattern);
599603
parsedQuery_.registerVariablesVisibleInQueryBody(visibleVariables_);
600604
visibleVariables_.clear();
@@ -605,8 +609,6 @@ ParsedQuery Visitor::visit(Parser::ModifyContext* ctx) {
605609
checkTriples(op.toDelete_);
606610
visitIf(&op.with_, ctx->iri());
607611
parsedQuery_._clause = parsedQuery::UpdateClause{op};
608-
parsedQuery_.datasetClauses_ =
609-
parsedQuery::DatasetClauses::fromClauses(visitVector(ctx->usingClause()));
610612

611613
return parsedQuery_;
612614
}
@@ -1174,6 +1176,7 @@ ParsedQuery Visitor::visit(Parser::SelectQueryContext* ctx) {
11741176
parsedQuery_._clause = visit(ctx->selectClause());
11751177
parsedQuery_.datasetClauses_ = parsedQuery::DatasetClauses::fromClauses(
11761178
visitVector(ctx->datasetClause()));
1179+
activeDatasetClauses_ = parsedQuery_.datasetClauses_;
11771180
visitWhereClause(ctx->whereClause(), parsedQuery_);
11781181
parsedQuery_.addSolutionModifiers(visit(ctx->solutionModifier()));
11791182
return parsedQuery_;
@@ -2434,6 +2437,7 @@ ExpressionPtr Visitor::visitExists(Parser::GroupGraphPatternContext* pattern,
24342437
ParsedQuery query = std::exchange(parsedQuery_, std::move(queryBackup));
24352438
query.selectClause().setAsterisk();
24362439
query._rootGraphPattern = std::move(group);
2440+
query.datasetClauses_ = activeDatasetClauses_;
24372441
visibleVariables_ = std::move(visibleVariablesSoFar);
24382442
auto exists =
24392443
std::make_unique<sparqlExpression::ExistsExpression>(std::move(query));

src/parser/sparqlParser/SparqlQleverVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class SparqlQleverVisitor {
7878
// query. This may contain duplicates. A variable is added via
7979
// `addVisibleVariable`.
8080
std::vector<Variable> visibleVariables_{};
81+
ParsedQuery::DatasetClauses activeDatasetClauses_;
8182
PrefixMap prefixMap_{};
8283
// We need to remember the prologue (prefix declarations) when we encounter it
8384
// because we need it when we encounter a SERVICE query. When there is no

test/QueryPlannerTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,6 +2918,35 @@ TEST(QueryPlanner, GroupByRedundantParensAndVariables) {
29182918
TEST(QueryPlanner, Exists) {
29192919
auto xyz = h::IndexScanFromStrings("?x", "?y", "?z");
29202920
auto abc = h::IndexScanFromStrings("?a", "?b", "?c");
2921+
using V = Variable;
2922+
// Simple tests for EXISTS with FILTER, BIND, and GROUP BY.
29212923
h::expect("SELECT * { ?x ?y ?z FILTER EXISTS {?a ?b ?c}}",
29222924
h::Filter("EXISTS {?a ?b ?c}", h::ExistsJoin(xyz, abc)));
2925+
h::expect("SELECT * { ?x ?y ?z BIND(EXISTS {?a ?b ?c} as ?bound)}",
2926+
h::Bind(h::ExistsJoin(xyz, abc), "EXISTS {?a ?b ?c}",
2927+
Variable("?bound")));
2928+
h::expect(
2929+
"SELECT ?x (SAMPLE(EXISTS{?a ?b ?c}) as ?s) { ?x ?y ?z } GROUP BY ?x",
2930+
h::GroupBy({V{"?x"}}, {"(SAMPLE(EXISTS{?a ?b ?c}) as ?s)"},
2931+
h::ExistsJoin(xyz, abc)));
2932+
2933+
// Test the interaction of FROM [NAMED] with EXISTS.
2934+
2935+
using H = ad_utility::HashSet<std::string>;
2936+
auto xyzg = h::IndexScanFromStrings("?x", "?y", "?z", {}, H{"<g>"});
2937+
auto abcg = h::IndexScanFromStrings("?a", "?b", "?c", {}, H{"<g>"});
2938+
2939+
auto existsJoin = h::ExistsJoin(xyzg, abcg);
2940+
auto filter = h::Filter("EXISTS {?a ?b ?c}", existsJoin);
2941+
2942+
// Test all different kinds of queries.
2943+
// TODO<joka921> There is a more elegant way to reduce the code duplication
2944+
// (use a lambda that only changes the beginning of the query).
2945+
h::expect("SELECT * FROM <g> { ?x ?y ?z FILTER EXISTS {?a ?b ?c}}", filter);
2946+
h::expect("ASK FROM <g> { ?x ?y ?z FILTER EXISTS {?a ?b ?c}}", filter);
2947+
h::expect(
2948+
"CONSTRUCT {<a> <b> <c>} FROM <g> { ?x ?y ?z FILTER EXISTS {?a ?b ?c}}",
2949+
filter);
2950+
h::expect("Describe ?x FROM <g> { ?x ?y ?z FILTER EXISTS {?a ?b ?c}}",
2951+
h::Describe(::testing::_, filter));
29232952
}

0 commit comments

Comments
 (0)