Skip to content

Commit

Permalink
Fix assertion error for GRAPH with unconnected components
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinTF committed Feb 28, 2025
1 parent 8fe0642 commit 21c2e61
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 3 deletions.
12 changes: 10 additions & 2 deletions src/engine/QueryPlanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,15 +486,23 @@ QueryPlanner::TripleGraph QueryPlanner::createTripleGraph(
absl::StrSplit(sv.substr(1, sv.size() - 2), ' ')) {
std::string s{ad_utility::utf8ToLower(term)};
potentialTermsForCvar[t.s_.getVariable()].push_back(s);
if (activeGraphVariable_.has_value() ||
activeDatasetClauses_.defaultGraphs_.has_value()) {
AD_THROW(
"contains-word is not allowed inside GRAPH clauses or in queries "
"with FROM/FROM NAMED clauses.");
}
addNodeToTripleGraph(
TripleGraph::Node(tg._nodeStorage.size(), t.s_.getVariable(), s, t),
TripleGraph::Node{tg._nodeStorage.size(), t.s_.getVariable(), s, t},
tg);
numNodesInTripleGraph++;
}
} else if (t.p_.iri_ == CONTAINS_ENTITY_PREDICATE) {
entityTriples.push_back(&t);
} else {
addNodeToTripleGraph(TripleGraph::Node(tg._nodeStorage.size(), t), tg);
addNodeToTripleGraph(
TripleGraph::Node{tg._nodeStorage.size(), t, activeGraphVariable_},
tg);
numNodesInTripleGraph++;
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/engine/QueryPlanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ class QueryPlanner {
TripleGraph(const TripleGraph& other, vector<size_t> keepNodes);

struct Node {
Node(size_t id, SparqlTriple t) : id_(id), triple_(std::move(t)) {
Node(size_t id, SparqlTriple t,
std::optional<Variable> graphVariable = std::nullopt)
: id_(id), triple_(std::move(t)) {
if (isVariable(triple_.s_)) {
_variables.insert(triple_.s_.getVariable());
}
Expand All @@ -61,6 +63,9 @@ class QueryPlanner {
if (isVariable(triple_.o_)) {
_variables.insert(triple_.o_.getVariable());
}
if (graphVariable.has_value()) {
_variables.insert(std::move(graphVariable).value());
}
}

Node(size_t id, Variable cvar, std::string word, SparqlTriple t)
Expand Down
57 changes: 57 additions & 0 deletions test/QueryPlannerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2981,3 +2981,60 @@ TEST(QueryPlanner, Exists) {
"GRAPH ?g { ?u ?v ?c}}}",
filter);
}

// _____________________________________________________________________________
TEST(QueryPlanner, ContainsWordInGraphClause) {
{
auto qp = makeQueryPlanner();
auto query = SparqlParser::parseQuery(
"SELECT * { GRAPH ?g { ?s "
"<http://qlever.cs.uni-freiburg.de/builtin-functions/contains-word> "
"\"Test\" } }");
AD_EXPECT_THROW_WITH_MESSAGE_AND_TYPE(
qp.createExecutionTree(query),
::testing::HasSubstr(
"contains-word is not allowed inside GRAPH clauses "
"or in queries with FROM/FROM NAMED clauses."),
ad_utility::Exception);
}
{
auto qp = makeQueryPlanner();
auto query = SparqlParser::parseQuery(
"SELECT * { GRAPH <my-iri> { ?s "
"<http://qlever.cs.uni-freiburg.de/builtin-functions/contains-word> "
"\"Test\" } }");
AD_EXPECT_THROW_WITH_MESSAGE_AND_TYPE(
qp.createExecutionTree(query),
::testing::HasSubstr(
"contains-word is not allowed inside GRAPH clauses "
"or in queries with FROM/FROM NAMED clauses."),
ad_utility::Exception);
}
{
auto qp = makeQueryPlanner();
auto query = SparqlParser::parseQuery(
"SELECT * FROM <my-iri> WHERE { ?s "
"<http://qlever.cs.uni-freiburg.de/builtin-functions/contains-word> "
"\"Test\" }");
AD_EXPECT_THROW_WITH_MESSAGE_AND_TYPE(
qp.createExecutionTree(query),
::testing::HasSubstr(
"contains-word is not allowed inside GRAPH clauses "
"or in queries with FROM/FROM NAMED clauses."),
ad_utility::Exception);
}
}

// _____________________________________________________________________________
TEST(QueryPlanner, UnconnectedComponentsInGraphClause) {
h::expect("SELECT * WHERE { GRAPH ?g { ?s1 ?p1 ?o1 . ?s2 ?p2 ?o2 } }",
h::Join(h::Sort(h::IndexScanFromStrings("?s1", "?p1", "?o1", {}, {},
{Variable{"?g"}}, {3})),
h::Sort(h::IndexScanFromStrings("?s2", "?p2", "?o2", {}, {},
{Variable{"?g"}}, {3}))));
// Sanity check case without a GRAPH clause
h::expect(
"SELECT * WHERE { ?s1 ?p1 ?o1 . ?s2 ?p2 ?o2 }",
h::CartesianProductJoin(h::IndexScanFromStrings("?s1", "?p1", "?o1"),
h::IndexScanFromStrings("?s2", "?p2", "?o2")));
}

0 comments on commit 21c2e61

Please sign in to comment.