Skip to content

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 ​

sql
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:

sql
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:

sql
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:

sql
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:

KindFunctions
StringsSTR, LCASE, UCASE, STRLEN, CONCAT
TermsLANG, DATATYPE
Numbers+, -, *, /, ABS, ROUND, CEIL, FLOOR
ChoiceIF(condition, then, else)
Constantsa 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:

sql
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 | Car

VALUES ​

VALUES restricts a variable to a list of values:

sql
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.

sql
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:

  • VALUES is for restricting variables that the triple patterns also use. A VALUES variable that no pattern uses comes back null for any value that doesn't already occur in the database. To attach a constant to each row, use BIND instead.
  • A query needs at least one triple pattern; VALUES on its own is refused.
  • VALUES can't bind the variable of a GRAPH ?g { … } clause; see GRAPH.

pgRDF is released under the MIT license. Documentation built with VitePress, served via GitHub Pages.