diff --git a/lib/query_processing/src/expressions/functions/str_after.rs b/lib/query_processing/src/expressions/functions/str_after.rs index e48996f8..9c96221f 100644 --- a/lib/query_processing/src/expressions/functions/str_after.rs +++ b/lib/query_processing/src/expressions/functions/str_after.rs @@ -8,7 +8,8 @@ pub fn str_after(c: Column, s: String) -> Result { if let Some(range_to) = range_to { Some(&x[range_to + s.len()..]) } else { - Some(x) + // SPARQL 1.1 17.4.3.9/17.4.3.10: no occurrence gives the empty string + Some("") } } else { None diff --git a/lib/query_processing/src/expressions/functions/str_before.rs b/lib/query_processing/src/expressions/functions/str_before.rs index b1279082..271049cb 100644 --- a/lib/query_processing/src/expressions/functions/str_before.rs +++ b/lib/query_processing/src/expressions/functions/str_before.rs @@ -8,7 +8,8 @@ pub fn str_before(c: Column, s: String) -> Result { if let Some(range_to) = range_to { Some(&x[0..range_to]) } else { - Some(x) + // SPARQL 1.1 17.4.3.9/17.4.3.10: no occurrence gives the empty string + Some("") } } else { None diff --git a/py_maplib/tests/test_str_before_after.py b/py_maplib/tests/test_str_before_after.py new file mode 100644 index 00000000..aa00bb08 --- /dev/null +++ b/py_maplib/tests/test_str_before_after.py @@ -0,0 +1,51 @@ +import pytest + +from maplib import Model + +# SPARQL 1.1 17.4.3.9 (STRBEFORE) and 17.4.3.10 (STRAFTER): +# "If there is no such occurrence, an empty simple literal is returned." + + +@pytest.mark.parametrize( + "expression,expected", + [ + ('STRAFTER("abc", "b")', "c"), + ('STRAFTER("abc", "xyz")', ""), + ('STRAFTER("abc", "")', "abc"), + ('STRBEFORE("abc", "b")', "a"), + ('STRBEFORE("abc", "xyz")', ""), + ('STRBEFORE("abc", "")', ""), + ], +) +def test_str_before_after_simple_literal(expression, expected): + m = Model() + df = m.query(f"SELECT (STR({expression}) AS ?s) WHERE {{}}") + assert df["s"].to_list() == [expected] + + +@pytest.mark.parametrize( + "expression,expected", + [ + ('STRAFTER("abc"@en, "b")', "c"), + ('STRAFTER("abc"@en, "z")', ""), + ('STRBEFORE("abc"@en, "b")', "a"), + ('STRBEFORE("abc"@en, "z")', ""), + ], +) +def test_str_before_after_lang_string(expression, expected): + m = Model() + df = m.query(f"SELECT (STR({expression}) AS ?s) WHERE {{}}") + assert df["s"].to_list() == [expected] + + +def test_str_after_no_match_on_data(): + m = Model() + m.insert( + """PREFIX ex: + CONSTRUCT { ex:a ex:v "prefix_a" . ex:b ex:v "other_b" . } WHERE {}""" + ) + df = m.query( + """PREFIX ex: + SELECT ?x (STRAFTER(?v, "prefix_") AS ?s) WHERE { ?x ex:v ?v } ORDER BY ?x""" + ) + assert df["s"].to_list() == ["a", ""]