From b33d85bc7d2a329ef480f9a5282e93ddf93228e7 Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:45:34 +0100 Subject: [PATCH 01/12] Correct WHERE parsing for CONSTRUCT WHERE --- .../sparqlParser/SparqlQleverVisitor.cpp | 48 +++++++++++++++++++ src/parser/sparqlParser/SparqlQleverVisitor.h | 5 ++ 2 files changed, 53 insertions(+) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index 9df20dd5ba..d435d6f98a 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -261,6 +261,52 @@ Alias Visitor::visit(Parser::AliasWithoutBracketsContext* ctx) { return {visitExpressionPimpl(ctx->expression()), visit(ctx->var())}; } +// ____________________________________________________________________________________ +parsedQuery::BasicGraphPattern Visitor::toGraphPattern( + const ad_utility::sparql_types::Triples& triples) { + parsedQuery::BasicGraphPattern pattern{}; + pattern._triples.reserve(triples.size()); + for (const auto& triple : triples) { + auto toTripleComponent = [](T&& item) { + namespace tc = ad_utility::triple_component; + if constexpr (ad_utility::isSimilar) { + return TripleComponent{item}; + } else if constexpr (ad_utility::isSimilar) { + return TripleComponent{ + tc::Literal::fromStringRepresentation(item.toSparql())}; + } else if constexpr (ad_utility::isSimilar) { + return TripleComponent{ + tc::Iri::fromStringRepresentation(item.toSparql())}; + } else if constexpr (ad_utility::isSimilar) { + return TripleComponent{ + ParsedQuery::blankNodeToInternalVariable(item.toSparql())}; + } else { + static_assert(ad_utility::alwaysFalse); + } + }; + auto subject = std::visit(toTripleComponent, triple.at(0)); + auto predicate = std::visit( + [](T&& item) -> PropertyPath { + if constexpr (ad_utility::isSimilar) { + return PropertyPath::fromVariable(item); + } else if constexpr (ad_utility::isSimilar) { + return PropertyPath::fromIri(item.toSparql()); + } else if constexpr (ad_utility::isSimilar) { + return PropertyPath::fromVariable( + ParsedQuery::blankNodeToInternalVariable(item.toSparql())); + } else { + static_assert(ad_utility::isSimilar); + AD_THROW("Converting a literal to a property path is not allowed."); + } + }, + triple.at(1)); + auto object = std::visit(toTripleComponent, triple.at(2)); + pattern._triples.push_back(SparqlTriple{ + std::move(subject), std::move(predicate), std::move(object)}); + } + return pattern; +} + // ____________________________________________________________________________________ ParsedQuery Visitor::visit(Parser::ConstructQueryContext* ctx) { ParsedQuery query; @@ -273,6 +319,8 @@ ParsedQuery Visitor::visit(Parser::ConstructQueryContext* ctx) { } else { query._clause = parsedQuery::ConstructClause{ visitOptional(ctx->triplesTemplate()).value_or(Triples{})}; + query._rootGraphPattern._graphPatterns.emplace_back( + toGraphPattern(query.constructClause().triples_)); } query.addSolutionModifiers(visit(ctx->solutionModifier())); diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.h b/src/parser/sparqlParser/SparqlQleverVisitor.h index fb1cb9c05c..43cd21c6d4 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.h +++ b/src/parser/sparqlParser/SparqlQleverVisitor.h @@ -598,4 +598,9 @@ class SparqlQleverVisitor { void warnOrThrowIfUnboundVariables(auto* ctx, const SparqlExpressionPimpl& expression, std::string_view clauseName); + + // Convert an instance of `Triples` to a `BasicGraphPattern` so it can be used + // just like a WHERE clause. + static parsedQuery::BasicGraphPattern toGraphPattern( + const ad_utility::sparql_types::Triples& triples); }; From 7a279d2fc99e5bec4f22b1eb05e3cf72a234a0ee Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:11:46 +0100 Subject: [PATCH 02/12] Don't convert blank nodes into variables just yet --- src/parser/sparqlParser/SparqlQleverVisitor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index d435d6f98a..d1aa75cced 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -317,6 +317,9 @@ ParsedQuery Visitor::visit(Parser::ConstructQueryContext* ctx) { .value_or(parsedQuery::ConstructClause{}); visitWhereClause(ctx->whereClause(), query); } else { + isInsideConstructTriples_ = true; + auto cleanup = + absl::Cleanup{[this]() { isInsideConstructTriples_ = false; }}; query._clause = parsedQuery::ConstructClause{ visitOptional(ctx->triplesTemplate()).value_or(Triples{})}; query._rootGraphPattern._graphPatterns.emplace_back( From 3fbd940f55ad44b3dc8f97a32a3981994027f6ae Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:52:01 +0100 Subject: [PATCH 03/12] Apply sonarcloud suggestions --- src/parser/sparqlParser/SparqlQleverVisitor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index d1aa75cced..3b2b978ae0 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -267,7 +267,7 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( parsedQuery::BasicGraphPattern pattern{}; pattern._triples.reserve(triples.size()); for (const auto& triple : triples) { - auto toTripleComponent = [](T&& item) { + auto toTripleComponent = [](const T& item) { namespace tc = ad_utility::triple_component; if constexpr (ad_utility::isSimilar) { return TripleComponent{item}; @@ -286,7 +286,7 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( }; auto subject = std::visit(toTripleComponent, triple.at(0)); auto predicate = std::visit( - [](T&& item) -> PropertyPath { + [](const T& item) -> PropertyPath { if constexpr (ad_utility::isSimilar) { return PropertyPath::fromVariable(item); } else if constexpr (ad_utility::isSimilar) { @@ -301,8 +301,8 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( }, triple.at(1)); auto object = std::visit(toTripleComponent, triple.at(2)); - pattern._triples.push_back(SparqlTriple{ - std::move(subject), std::move(predicate), std::move(object)}); + pattern._triples.emplace_back(std::move(subject), std::move(predicate), + std::move(object)); } return pattern; } From dcc4025a26d344cb7f6e4e64a6514878a567a411 Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Tue, 4 Feb 2025 17:02:55 +0100 Subject: [PATCH 04/12] Fix unit test --- test/SparqlAntlrParserTest.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/SparqlAntlrParserTest.cpp b/test/SparqlAntlrParserTest.cpp index 3bd820256e..2127938d52 100644 --- a/test/SparqlAntlrParserTest.cpp +++ b/test/SparqlAntlrParserTest.cpp @@ -1215,9 +1215,11 @@ TEST(SparqlParser, ConstructQuery) { m::pq::LimitOffset({10}), m::pq::OrderKeys({{Var{"?a"}, false}}))); // This case of the grammar is not useful without Datasets, but we still // support it. - expectConstructQuery("CONSTRUCT WHERE { ?a ?b }", - m::ConstructQuery({{Var{"?a"}, Iri{""}, Var{"?b"}}}, - m::GraphPattern())); + expectConstructQuery( + "CONSTRUCT WHERE { ?a ?b }", + m::ConstructQuery( + {{Var{"?a"}, Iri{""}, Var{"?b"}}}, + m::GraphPattern(m::Triples({{Var{"?a"}, "", Var{"?b"}}})))); // CONSTRUCT with datasets. expectConstructQuery( "CONSTRUCT { } FROM FROM NAMED FROM NAMED WHERE { }", From d1d68355b2bf0fb40c68a22408a16036857c3df5 Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Tue, 4 Feb 2025 18:11:25 +0100 Subject: [PATCH 05/12] Add missing unit tests and delete redundant code --- .../sparqlParser/SparqlQleverVisitor.cpp | 8 +++----- test/SparqlAntlrParserTest.cpp | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index 3b2b978ae0..1d640c57f9 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -291,12 +291,10 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( return PropertyPath::fromVariable(item); } else if constexpr (ad_utility::isSimilar) { return PropertyPath::fromIri(item.toSparql()); - } else if constexpr (ad_utility::isSimilar) { - return PropertyPath::fromVariable( - ParsedQuery::blankNodeToInternalVariable(item.toSparql())); } else { - static_assert(ad_utility::isSimilar); - AD_THROW("Converting a literal to a property path is not allowed."); + static_assert(ad_utility::isSimilar || + ad_utility::isSimilar); + AD_THROW("Literals or blank nodes are not valid predicates."); } }, triple.at(1)); diff --git a/test/SparqlAntlrParserTest.cpp b/test/SparqlAntlrParserTest.cpp index 2127938d52..078be8d0e1 100644 --- a/test/SparqlAntlrParserTest.cpp +++ b/test/SparqlAntlrParserTest.cpp @@ -1220,6 +1220,25 @@ TEST(SparqlParser, ConstructQuery) { m::ConstructQuery( {{Var{"?a"}, Iri{""}, Var{"?b"}}}, m::GraphPattern(m::Triples({{Var{"?a"}, "", Var{"?b"}}})))); + + // Blank nodes turn into variables inside WHERE. + expectConstructQuery( + "CONSTRUCT WHERE { [] ?b }", + m::ConstructQuery( + {{BlankNode{true, "0"}, Iri{""}, Var{"?b"}}}, + m::GraphPattern(m::Triples( + {{Var{absl::StrCat(QLEVER_INTERNAL_BLANKNODE_VARIABLE_PREFIX, + "g_0")}, + "", Var{"?b"}}})))); + + // Test another variant to cover all cases. + expectConstructQuery( + "CONSTRUCT WHERE { ?foo \"Abc\" }", + m::ConstructQuery( + {{Iri{""}, Var{"?foo"}, Literal{"\"Abc\""}}}, + m::GraphPattern(m::Triples( + {{iri(""), PropertyPath::fromVariable(Var{"?foo"}), + lit("\"Abc\"")}})))); // CONSTRUCT with datasets. expectConstructQuery( "CONSTRUCT { } FROM FROM NAMED FROM NAMED WHERE { }", From 4394ba1a4de91cc028d6262e35c54a56377823ed Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Tue, 4 Feb 2025 18:17:50 +0100 Subject: [PATCH 06/12] Cover remaining branch --- src/parser/sparqlParser/SparqlQleverVisitor.h | 3 +++ test/SparqlAntlrParserTest.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.h b/src/parser/sparqlParser/SparqlQleverVisitor.h index 43cd21c6d4..d4d740e5bf 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.h +++ b/src/parser/sparqlParser/SparqlQleverVisitor.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include "engine/sparqlExpressions/AggregateExpression.h" #include "engine/sparqlExpressions/NaryExpression.h" @@ -603,4 +604,6 @@ class SparqlQleverVisitor { // just like a WHERE clause. static parsedQuery::BasicGraphPattern toGraphPattern( const ad_utility::sparql_types::Triples& triples); + + FRIEND_TEST(SparqlParser, ensureExceptionOnInvalidGraphTerm); }; diff --git a/test/SparqlAntlrParserTest.cpp b/test/SparqlAntlrParserTest.cpp index 078be8d0e1..bf35ddf5d9 100644 --- a/test/SparqlAntlrParserTest.cpp +++ b/test/SparqlAntlrParserTest.cpp @@ -1246,6 +1246,16 @@ TEST(SparqlParser, ConstructQuery) { m::Graphs{iri(""), iri("")})); } +// _____________________________________________________________________________ +TEST(SparqlParser, ensureExceptionOnInvalidGraphTerm) { + EXPECT_THROW(SparqlQleverVisitor::toGraphPattern( + {{Var{"?a"}, BlankNode{true, "0"}, Var{"?b"}}}), + ad_utility::Exception); + EXPECT_THROW(SparqlQleverVisitor::toGraphPattern( + {{Var{"?a"}, Literal{"\"Abc\""}, Var{"?b"}}}), + ad_utility::Exception); +} + // Test that ASK queries are parsed as they should. TEST(SparqlParser, AskQuery) { // Some helper functions and abbreviations. From eaacc7d07ee8af2bc7ea2d9afc8c2c4c9f076d90 Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Wed, 5 Feb 2025 10:29:51 +0100 Subject: [PATCH 07/12] Move lambdas out of loop --- .../sparqlParser/SparqlQleverVisitor.cpp | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index f80c3208bb..68873ca85a 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -283,38 +283,37 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( const ad_utility::sparql_types::Triples& triples) { parsedQuery::BasicGraphPattern pattern{}; pattern._triples.reserve(triples.size()); + auto toTripleComponent = [](const T& item) { + namespace tc = ad_utility::triple_component; + if constexpr (ad_utility::isSimilar) { + return TripleComponent{item}; + } else if constexpr (ad_utility::isSimilar) { + return TripleComponent{ + tc::Literal::fromStringRepresentation(item.toSparql())}; + } else if constexpr (ad_utility::isSimilar) { + return TripleComponent{ + tc::Iri::fromStringRepresentation(item.toSparql())}; + } else if constexpr (ad_utility::isSimilar) { + return TripleComponent{ + ParsedQuery::blankNodeToInternalVariable(item.toSparql())}; + } else { + static_assert(ad_utility::alwaysFalse); + } + }; + auto toPropertyPath = [](const T& item) -> PropertyPath { + if constexpr (ad_utility::isSimilar) { + return PropertyPath::fromVariable(item); + } else if constexpr (ad_utility::isSimilar) { + return PropertyPath::fromIri(item.toSparql()); + } else { + static_assert(ad_utility::isSimilar || + ad_utility::isSimilar); + AD_THROW("Literals or blank nodes are not valid predicates."); + } + }; for (const auto& triple : triples) { - auto toTripleComponent = [](const T& item) { - namespace tc = ad_utility::triple_component; - if constexpr (ad_utility::isSimilar) { - return TripleComponent{item}; - } else if constexpr (ad_utility::isSimilar) { - return TripleComponent{ - tc::Literal::fromStringRepresentation(item.toSparql())}; - } else if constexpr (ad_utility::isSimilar) { - return TripleComponent{ - tc::Iri::fromStringRepresentation(item.toSparql())}; - } else if constexpr (ad_utility::isSimilar) { - return TripleComponent{ - ParsedQuery::blankNodeToInternalVariable(item.toSparql())}; - } else { - static_assert(ad_utility::alwaysFalse); - } - }; auto subject = std::visit(toTripleComponent, triple.at(0)); - auto predicate = std::visit( - [](const T& item) -> PropertyPath { - if constexpr (ad_utility::isSimilar) { - return PropertyPath::fromVariable(item); - } else if constexpr (ad_utility::isSimilar) { - return PropertyPath::fromIri(item.toSparql()); - } else { - static_assert(ad_utility::isSimilar || - ad_utility::isSimilar); - AD_THROW("Literals or blank nodes are not valid predicates."); - } - }, - triple.at(1)); + auto predicate = std::visit(toPropertyPath, triple.at(1)); auto object = std::visit(toTripleComponent, triple.at(2)); pattern._triples.emplace_back(std::move(subject), std::move(predicate), std::move(object)); From 2b7b1b64d41983f2f342d8abc0a3be7a17c10105 Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Wed, 5 Feb 2025 10:51:48 +0100 Subject: [PATCH 08/12] Use TurtleParser to handle special syntax --- src/parser/sparqlParser/SparqlQleverVisitor.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index 68873ca85a..d8d478bc4e 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -287,17 +287,14 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( namespace tc = ad_utility::triple_component; if constexpr (ad_utility::isSimilar) { return TripleComponent{item}; - } else if constexpr (ad_utility::isSimilar) { - return TripleComponent{ - tc::Literal::fromStringRepresentation(item.toSparql())}; - } else if constexpr (ad_utility::isSimilar) { - return TripleComponent{ - tc::Iri::fromStringRepresentation(item.toSparql())}; } else if constexpr (ad_utility::isSimilar) { return TripleComponent{ ParsedQuery::blankNodeToInternalVariable(item.toSparql())}; } else { - static_assert(ad_utility::alwaysFalse); + static_assert(ad_utility::isSimilar || + ad_utility::isSimilar); + return RdfStringParser>::parseTripleObject( + item.toSparql()); } }; auto toPropertyPath = [](const T& item) -> PropertyPath { From 8f247159f9888609ccfd6961b2f272818aa6d17b Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:07:34 +0100 Subject: [PATCH 09/12] Add unit test to test extra case --- test/SparqlAntlrParserTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/SparqlAntlrParserTest.cpp b/test/SparqlAntlrParserTest.cpp index 9a1004b93c..cca4ebeddb 100644 --- a/test/SparqlAntlrParserTest.cpp +++ b/test/SparqlAntlrParserTest.cpp @@ -1233,12 +1233,12 @@ TEST(SparqlParser, ConstructQuery) { // Test another variant to cover all cases. expectConstructQuery( - "CONSTRUCT WHERE { ?foo \"Abc\" }", + "CONSTRUCT WHERE { ?foo \"Abc\"@en }", m::ConstructQuery( - {{Iri{""}, Var{"?foo"}, Literal{"\"Abc\""}}}, + {{Iri{""}, Var{"?foo"}, Literal{"\"Abc\"@en"}}}, m::GraphPattern(m::Triples( {{iri(""), PropertyPath::fromVariable(Var{"?foo"}), - lit("\"Abc\"")}})))); + lit("\"Abc\"", "@en")}})))); // CONSTRUCT with datasets. expectConstructQuery( "CONSTRUCT { } FROM FROM NAMED FROM NAMED WHERE { }", From b70ddee3223e5ca579f7e70590fac2bb18af964d Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:23:28 +0100 Subject: [PATCH 10/12] Add clarifying comments --- src/parser/sparqlParser/SparqlQleverVisitor.cpp | 6 ++++++ src/parser/sparqlParser/SparqlQleverVisitor.h | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index d8d478bc4e..66b1b60a92 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -288,6 +288,8 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( if constexpr (ad_utility::isSimilar) { return TripleComponent{item}; } else if constexpr (ad_utility::isSimilar) { + // Blank Nodes in the pattern are to be treated as internal variables + // inside WHERE. return TripleComponent{ ParsedQuery::blankNodeToInternalVariable(item.toSparql())}; } else { @@ -305,6 +307,7 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( } else { static_assert(ad_utility::isSimilar || ad_utility::isSimilar); + // This case can only happen if there's a bug in the SPARQL parser. AD_THROW("Literals or blank nodes are not valid predicates."); } }; @@ -328,6 +331,9 @@ ParsedQuery Visitor::visit(Parser::ConstructQueryContext* ctx) { .value_or(parsedQuery::ConstructClause{}); visitWhereClause(ctx->whereClause(), query); } else { + // For `CONTRUCT WHERE`, the CONSTRUCT template and the WHERE clause are + // syntactically the same, so we set the flag to true to keep the blank + // nodes, and convert them into variables during `toGraphPattern`. isInsideConstructTriples_ = true; auto cleanup = absl::Cleanup{[this]() { isInsideConstructTriples_ = false; }}; diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.h b/src/parser/sparqlParser/SparqlQleverVisitor.h index d4d740e5bf..b3d629145a 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.h +++ b/src/parser/sparqlParser/SparqlQleverVisitor.h @@ -601,7 +601,10 @@ class SparqlQleverVisitor { std::string_view clauseName); // Convert an instance of `Triples` to a `BasicGraphPattern` so it can be used - // just like a WHERE clause. + // just like a WHERE clause. Most of the time this just changes the type and + // stays semantically the same, but for blank nodes, this step converts them + // into internal variables so they are interpreted correctly by the query + // planner. static parsedQuery::BasicGraphPattern toGraphPattern( const ad_utility::sparql_types::Triples& triples); From 6402ba2bf39ac5022f4df3c4a1bec6650a356c3a Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:30:03 +0100 Subject: [PATCH 11/12] Fix typo --- src/parser/sparqlParser/SparqlQleverVisitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index 66b1b60a92..494952b0e9 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -331,7 +331,7 @@ ParsedQuery Visitor::visit(Parser::ConstructQueryContext* ctx) { .value_or(parsedQuery::ConstructClause{}); visitWhereClause(ctx->whereClause(), query); } else { - // For `CONTRUCT WHERE`, the CONSTRUCT template and the WHERE clause are + // For `CONSTRUCT WHERE`, the CONSTRUCT template and the WHERE clause are // syntactically the same, so we set the flag to true to keep the blank // nodes, and convert them into variables during `toGraphPattern`. isInsideConstructTriples_ = true; From 11dd6f3247568d5daeeb9ba049f6f68697a80403 Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:49:24 +0100 Subject: [PATCH 12/12] Use shorter concept --- src/parser/sparqlParser/SparqlQleverVisitor.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index 494952b0e9..f3d051145d 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -293,8 +293,7 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( return TripleComponent{ ParsedQuery::blankNodeToInternalVariable(item.toSparql())}; } else { - static_assert(ad_utility::isSimilar || - ad_utility::isSimilar); + static_assert(ad_utility::SimilarToAny); return RdfStringParser>::parseTripleObject( item.toSparql()); } @@ -305,8 +304,7 @@ parsedQuery::BasicGraphPattern Visitor::toGraphPattern( } else if constexpr (ad_utility::isSimilar) { return PropertyPath::fromIri(item.toSparql()); } else { - static_assert(ad_utility::isSimilar || - ad_utility::isSimilar); + static_assert(ad_utility::SimilarToAny); // This case can only happen if there's a bug in the SPARQL parser. AD_THROW("Literals or blank nodes are not valid predicates."); }