BIND and VALUES
BIND(expression AS ?v) computes a value for each solution and gives it a name. VALUES supplies a fixed list of values for one or more variables.
Examples use the sample data.
BIND
SELECT * FROM pgrdf.sparql($$
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>
SELECT ?label ?band
WHERE { ?p foaf:name ?name ; ex:age ?age .
BIND(CONCAT(UCASE(?name), " (", STR(?age), ")") AS ?label)
BIND(IF(?age >= 30, "30+", "under 30") AS ?band) }
ORDER BY ?label
$$);
-- {"band": "30+", "label": "ALICE (34)"}
-- {"band": "30+", "label": "BOB (41)"}
-- {"band": "under 30", "label": "CAROL (29)"}A bound variable can be used later in the query, for example in a FILTER:
SELECT * FROM pgrdf.sparql($$
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?n ?u
WHERE { ?p foaf:name ?n
BIND(UCASE(?n) AS ?u)
FILTER(?u = "BOB") }
$$);
-- {"n": "Bob", "u": "BOB"}BIND can also come first, to fix a variable before the patterns that use it:
SELECT * FROM pgrdf.sparql($$
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>
SELECT ?p ?name
WHERE { BIND(ex:bob AS ?p)
?p foaf:name ?name }
$$);
-- {"p": "http://example.org/bob", "name": "Bob"}Expressions in SELECT
SELECT (expression AS ?v) works the same way:
SELECT * FROM pgrdf.sparql($$
PREFIX ex: <http://example.org/>
SELECT ?p (?age * 12 AS ?months)
WHERE { ?p ex:age ?age }
ORDER BY ?p
$$);
-- {"p": "http://example.org/alice", "months": "408"}
-- {"p": "http://example.org/bob", "months": "492"}
-- {"p": "http://example.org/carol", "months": "348"}What BIND can compute
BIND and SELECT expressions produce values:
| Kind | Functions |
|---|---|
| Strings | STR, LCASE, UCASE, STRLEN, CONCAT |
| Terms | LANG, DATATYPE |
| Numbers | +, -, *, /, ABS, ROUND, CEIL, FLOOR |
| Choice | IF(condition, then, else) |
| Constants | a literal ("tag") or an IRI (ex:thing) |
Division returns a decimal: 41 / 2 comes back as "20.5000000000000000".
Tests that return true or false — comparisons, IN, isIRI, isLiteral, BOUND, CONTAINS, STRSTARTS, STRENDS, REGEX — are for FILTER, not BIND. COALESCE, SUBSTR, IRI(), NOW() and other functions not listed here are not supported. An expression pgRDF can't compute is refused with an error that names it, for example:
ERROR: sparql: BIND expression for ?x not translatable: Coalesce(...)Values are plain strings in the result rows, so the SQL around pgrdf.sparql() can do the rest:
SELECT sparql->>'name' AS name,
coalesce(sparql->>'mbox', 'none') AS mbox,
left(sparql->>'name', 3) AS short
FROM pgrdf.sparql($$
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE { ?p foaf:name ?name OPTIONAL { ?p foaf:mbox ?mbox } }
ORDER BY ?name
$$);
-- name | mbox | short
-- -------+--------------------------+-------
-- Alice | mailto:alice@example.org | Ali
-- Bob | none | Bob
-- Carol | mailto:carol@example.org | CarVALUES
VALUES restricts a variable to a list of values:
SELECT * FROM pgrdf.sparql($$
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>
SELECT ?p ?name
WHERE { VALUES ?p { ex:alice ex:carol }
?p foaf:name ?name }
ORDER BY ?name
$$);
-- {"p": "http://example.org/alice", "name": "Alice"}
-- {"p": "http://example.org/carol", "name": "Carol"}Several variables at once take rows of values; each row must match as a whole. UNDEF leaves a variable unconstrained in that row.
SELECT * FROM pgrdf.sparql($$
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>
SELECT ?p ?name
WHERE { VALUES (?p ?name) { (ex:alice "Alice") (ex:bob "Robert") }
?p foaf:name ?name }
$$);
-- {"p": "http://example.org/alice", "name": "Alice"}Bob's name isn't "Robert", so only Alice's row matches. A VALUES block after the closing } of WHERE works too.
Limits:
VALUESis for restricting variables that the triple patterns also use. AVALUESvariable that no pattern uses comes backnullfor any value that doesn't already occur in the database. To attach a constant to each row, useBINDinstead.- A query needs at least one triple pattern;
VALUESon its own is refused. VALUEScan't bind the variable of aGRAPH ?g { … }clause; see GRAPH.