From 01f91a6f521bbe76cba3972646756bdb2cf5419a Mon Sep 17 00:00:00 2001 From: RobinTF <83676088+RobinTF@users.noreply.github.com> Date: Mon, 3 Mar 2025 10:18:31 +0100 Subject: [PATCH] Apply filter on neutral element (#1842) The neutral element can still get filtered out if a constant-expression `FILTER` clause is present. This PR correctly applies this filter. This corrects the beahviors for queries such as ``` ASK { FILTER (1 < 0) } ``` Which should return `false`, as the filter filters out all possible results, even if they have no bound variables. --- src/engine/QueryPlanner.cpp | 5 ++++- test/QueryPlannerTest.cpp | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/engine/QueryPlanner.cpp b/src/engine/QueryPlanner.cpp index be7cfe27d5..e70c56b139 100644 --- a/src/engine/QueryPlanner.cpp +++ b/src/engine/QueryPlanner.cpp @@ -262,7 +262,10 @@ std::vector QueryPlanner::optimize( if (candidatePlans.at(0).empty()) { // This happens if either graph pattern is an empty group, // or it only consists of a MINUS clause (which then has no effect). - return {makeSubtreePlan(_qec)}; + std::vector neutralPlans{makeSubtreePlan(_qec)}; + // Neutral element can potentially still get filtered out + applyFiltersIfPossible(neutralPlans, rootPattern->_filters); + return neutralPlans; } return candidatePlans[0]; } diff --git a/test/QueryPlannerTest.cpp b/test/QueryPlannerTest.cpp index e2135f80c5..cbd9e380be 100644 --- a/test/QueryPlannerTest.cpp +++ b/test/QueryPlannerTest.cpp @@ -2981,3 +2981,15 @@ TEST(QueryPlanner, Exists) { "GRAPH ?g { ?u ?v ?c}}}", filter); } + +// _____________________________________________________________________________ +TEST(QueryPlanner, FilterOnNeutralElement) { + h::expect("SELECT * { FILTER(false) }", + h::Filter("false", h::NeutralElement())); + h::expect("SELECT * { FILTER(true) }", + h::Filter("true", h::NeutralElement())); + + h::expect("SELECT * { { SELECT * WHERE { FILTER(false) } } VALUES ?x { 1 } }", + h::CartesianProductJoin(h::Filter("false", h::NeutralElement()), + h::ValuesClause("VALUES (?x) { (1) }"))); +}