diff --git a/test/QueryPlannerTest.cpp b/test/QueryPlannerTest.cpp index 93b503d1f4..0d75818443 100644 --- a/test/QueryPlannerTest.cpp +++ b/test/QueryPlannerTest.cpp @@ -10,6 +10,7 @@ #include "engine/SpatialJoin.h" #include "parser/GraphPatternOperation.h" #include "parser/SparqlParser.h" +#include "parser/SpatialQuery.h" #include "parser/data/Variable.h" #include "util/TripleComponentTestHelpers.h" @@ -1634,6 +1635,33 @@ TEST(QueryPlanner, SpatialJoinService) { " } }", h::SpatialJoin(1, -1, scan("?x", "

", "?y"), scan("?a", "

", "?b"))); + AD_EXPECT_THROW_WITH_MESSAGE( + h::expect("PREFIX spatialSearch: " + "" + "SELECT * WHERE {" + "SERVICE spatialSearch: {" + "_:config spatialSearch:left ?y ;" + "spatialSearch:right ?b ;" + "spatialSearch:maxDistance " + "\"1\"^^ ." + "}}", + ::testing::_), + ::testing::ContainsRegex( + "SpatialJoin needs two children, but at least one is missing")); + + // TODO test two SERVICE spatial that share ?left + + // TODO change / add tests + + // TODO tests with incomplete config + + // TODO Migrate tests from (SpatialJoin, maxDistanceParsingTest) + // here +} + +TEST(QueryPlanner, SpatialJoinLegacyPredicateSupport) { + auto scan = h::IndexScanFromStrings; + // For maxDistance the special predicate remains supported h::expect( "SELECT * WHERE {" @@ -1653,13 +1681,6 @@ TEST(QueryPlanner, SpatialJoinService) { ::testing::_), ::testing::ContainsRegex("Please use SERVICE")); - // TODO test two SERVICE spatial that share ?left - - // TODO change / add tests - - // TODO Migrate tests from (SpatialJoin, maxDistanceParsingTest) - // here - AD_EXPECT_THROW_WITH_MESSAGE( h::expect("SELECT ?x ?y WHERE {" "?x

?y." @@ -1692,20 +1713,6 @@ TEST(QueryPlanner, SpatialJoinService) { " ?y }", ::testing::_)); - AD_EXPECT_THROW_WITH_MESSAGE( - h::expect("PREFIX spatialSearch: " - "" - "SELECT * WHERE {" - "SERVICE spatialSearch: {" - "_:config spatialSearch:left ?y ;" - "spatialSearch:right ?b ;" - "spatialSearch:maxDistance " - "\"1\"^^ ." - "}}", - ::testing::_), - ::testing::ContainsRegex( - "SpatialJoin needs two children, but at least one is missing")); - AD_EXPECT_THROW_WITH_MESSAGE(h::expect("SELECT ?x ?y WHERE {" "?x

?y." "?a

?b." @@ -1800,6 +1807,90 @@ TEST(QueryPlanner, SpatialJoinService) { ::testing::ContainsRegex("unknown triple")); } +TEST(QueryPlanner, SpatialJoinLegacyMaxDistanceParsing) { + // test if the SpatialJoin operation parses the maximum distance correctly + auto testMaxDistance = [](std::string distanceIRI, long long distance, + bool shouldThrow) { + auto qec = ad_utility::testing::getQec(); + TripleComponent subject{Variable{"?subject"}}; + TripleComponent object{Variable{"?object"}}; + SparqlTriple triple{subject, distanceIRI, object}; + if (shouldThrow) { + ASSERT_ANY_THROW( + parsedQuery::SpatialQuery{triple}.toSpatialJoinConfiguration()); + } else { + auto config = std::make_shared( + parsedQuery::SpatialQuery{triple}.toSpatialJoinConfiguration()); + std::shared_ptr spatialJoinOperation = + ad_utility::makeExecutionTree(qec, config, std::nullopt, + std::nullopt); + std::shared_ptr op = spatialJoinOperation->getRootOperation(); + SpatialJoin* spatialJoin = static_cast(op.get()); + ASSERT_TRUE(spatialJoin->getMaxDist().has_value()); + ASSERT_EQ(spatialJoin->getMaxDist(), distance); + ASSERT_FALSE(spatialJoin->getMaxResults().has_value()); + } + }; + + testMaxDistance("", 1000, false); + + testMaxDistance("", 0, false); + + testMaxDistance("", 20000000, false); + + testMaxDistance("", 123456789, false); + + // the following distance is slightly bigger than earths circumference. + // This distance should still be representable + testMaxDistance("", 45000000000, false); + + // distance must be positive + testMaxDistance("", -10, true); + + // some words start with an upper case + testMaxDistance("", 1000, true); + + // wrong keyword for the spatialJoin operation + testMaxDistance("", 1000, true); + + // "M" in meters is upper case + testMaxDistance("", 1000, true); + + // two > at the end + testMaxDistance(">", 1000, true); + + // distance must be given as integer + testMaxDistance("", 1000, true); + + // distance must be given as integer + testMaxDistance(">", 1000, true); + + // missing > at the end + testMaxDistance("", 1000, true); + + // suffix after correct iri + testMaxDistance("", 1000, true); + + // suffix after correct iri + testMaxDistance("", 1000, true); + + // suffix after number. + // Note that the usual stoll function would return + // 1000 instead of throwing an exception. To fix this mistake, a for loop + // has been added to the parsing, which checks, if each character (which + // should be converted to a number) is a digit + testMaxDistance("", 1000, true); + + // prefix before < + testMaxDistance("yxcv", 1000, true); + + // suffix after > + testMaxDistance("dfgh", 1000, true); +} + // __________________________________________________________________________ TEST(QueryPlanner, BindAtBeginningOfQuery) { h::expect(