Skip to content
Eric Prud'hommeaux edited this page Jun 3, 2019 · 1 revision

Migrated from https://www.w3.org/2001/sw/wiki/ShEx/Unique_UNIQUE

UNIQUE

Proposed for 2.3

A UNIQUE constraint takes an optional scope (FOCUS|GRAPH, default: FOCUS) and 1+ predicates, e.g.:

<T> {
  :fname LITERAL;
  :lname LITERAL;
  :title LITERAL+;
  :homepage IRI
  UNIQUE(GRAPH, :fname, :lname)
  UNIQUE(LANGTAG(:title))
  UNIQUE(GRAPH, :homepage)
}

UNIQUEs can appear arbitrarily nested in expressions:

<PersonShape> {
    foaf:givenName .;
    foaf:familyName
    UNIQUE(foaf:given, foaf:family)
  | foaf:name .
    UNIQUE(foaf:name)
}

UNIQUEs scoped to the FOCUSNODE can be dispatched immediately. Those scoped to the GRAPH or DATASET must have their values noted and associated with the UNIQUE constraint, noting any possible conflicts during insertion.

Shortcomings

It's possible we'd want uniques that span shapes, e.g. if the following data were permissible:

{ <s1> :code "1234"; :dept [ :code "5678" ] .
  <s2> :code "1234"; :dept [ :code "8765" ] }

but this were not:

{ <s1> :code "1234"; :dept [ :code "5678" ] .
  <s2> :code "1234"; :dept [ :code "5678" ] }

There's no way to stipulate uniqueness across repeated properties, e.g. if we wanted to make sure that creators from a.example were unique in the graph but creators from b.example were not:

schema

<nowiki><S></nowiki> { :creator PATTERN "^http://a\\.example/",
      :creator PATTERN "^http://b\\.example/"
}

**failing data((

{ <s1> :creator <http://a.example/1> ; :creator <http://b.example/2> .
  <s2> :creator <http://a.example/3> ; :creator <http://b.example/2> .
}

Alternative Syntax - on shape

The UNIQUE constraints could go on the shape.

<T>
  UNIQUE(GRAPH, :fname, :lname)
  UNIQUE(LANGTAG(:title))
  UNIQUE(GRAPH, :homepage)
  {
    :fname LITERAL;
    :lname LITERAL;
    :title LITERAL+;
    :homepage IRI
  }

This makes evaluation of predicates in disjuncts weird, e.g.

<PersonShape> UNIQUE(foaf:given, foaf:family) UNIQUE(foaf:name)
  { foaf:givenName .; foaf:familyName | foaf:name .}

where the semantics for enforcing UNIQUE(foaf:given, foaf:family) over the data { <nowiki><s></nowiki> :foaf:name "Bob Smith". } are a bit weird and "NULL-y".

Clone this wiki locally