Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/query_processing/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub enum QueryProcessingError {
ExpectedIntegerArgument(Function),
#[error("Error parsing literal {0}")]
ParseLiteralError(RepresentationError),
#[error("UDF function error {0}")]
#[error("UDF function error: {0}")]
UDFError(String),
#[error(
"Custom function not found: {0}, it is possible to define a function using m.add_udf()"
Expand Down
49 changes: 48 additions & 1 deletion py_maplib/tests/test_udfs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import polars as pl
from maplib import Model, xsd
import pytest
from polars import DataFrame
from maplib import Model, xsd, RDFType, MaplibException

def f(df: pl.DataFrame) -> pl.Series:
df = df.with_columns(
Expand All @@ -13,6 +15,12 @@ def g(df: pl.DataFrame) -> pl.DataFrame:
)
return df

def h(df: DataFrame) -> pl.DataFrame:
df = df.with_columns(
(pl.col("0") + pl.lit("_suf")).alias("out")
)
return df

def test_udf_query():
m = Model()
m.add_udf("urn:maplib:plusarg", f, xsd.integer)
Expand Down Expand Up @@ -49,8 +57,47 @@ def test_udf_query_strings():
print(result)
assert result.get_column("found").sort().to_list() == [None, False, False, True]

def test_udf_query_iris():
m = Model()
m.add_udf("urn:maplib:addsuf", h, RDFType.IRI, [RDFType.IRI])
m.reads("""
<http://example.org/a> <urn:maplib:hasiri> <http://example.org/abe> .
<http://example.org/a> <urn:maplib:hasiri> <http://example.org/abc> .
<http://example.org/a> <urn:maplib:hasiri> <http://example.org/abd> .
""", "turtle")
result = m.query("""
SELECT * {
?a <urn:maplib:hasiri> ?s1 .
BIND(<urn:maplib:addsuf>(?s1) AS ?suffed)
}
""")
assert result.get_column("suffed").sort().to_list() == ['<http://example.org/abc_suf>', '<http://example.org/abd_suf>', '<http://example.org/abe_suf>']

def test_list_udfs():
m = Model()
assert m.list_udfs() == []
m.add_udf("urn:maplib:myudf", f, xsd.integer)
assert m.list_udfs() == ["urn:maplib:myudf"]

def test_udf_error_message():
m = Model()
with pytest.raises(Exception, match="is not callable"):
m.add_udf("urn:maplib:test", "test", xsd.boolean, [xsd.string])

def test_udf_wrong_output_type():
m = Model()
m.add_udf("urn:maplib:findabc", g, xsd.integer, [xsd.string])
m.reads("""
<http://example.org/a> <urn:maplib:hasstr> "1" .
<http://example.org/a> <urn:maplib:hasstr> "ab2" .
<http://example.org/b> <urn:maplib:hasstr> "abc" .
<http://example.org/b> <urn:maplib:hasstr> 1 .
""", "turtle")
with pytest.raises(MaplibException) as e:
result = m.query("""
SELECT * {
?a <urn:maplib:hasstr> ?s1 .
BIND(<urn:maplib:findabc>(?s1) AS ?found)
}
""")
assert "did not have the expected type" in e
Loading