<?xml version="1.0" encoding="utf-8"?><!-- -*- mode: nxml; -*- -->
<?xml-stylesheet type="text/xsl" href="xmlspec.xsl"?>
<!DOCTYPE spec PUBLIC "-//W3C//DTD Specification V2.1//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd" [
<!ENTITY version "1.0">
<!ENTITY ne "≠">
<!ENTITY ouml "ö">
<!ENTITY times "×">
<!ENTITY order "£">
<!ENTITY le "≤">
<!ENTITY cellback "#d0d9fa">
<!ENTITY eacute "é">
<!ENTITY copy "©">
<!ENTITY sect "§">
<!ENTITY mdash "&#8212;">
<!ENTITY nbsp "&#160;">
]>
<spec w3c-doctype="wd">
  <header>
    <title>A Direct Mapping of Relational Data to RDF</title>
    <w3c-designation>Internal Working Draft</w3c-designation>
    <w3c-doctype>Editor's Draft 9 November 2010</w3c-doctype>
    <!-- notice>Notice this!!</notice -->
    <publoc>
      $Id: Overview.xml,v 1.60 2011/03/03 18:26:31 eric Exp $
    </publoc>
    <prevlocs>
      <loc href="http://www.w3.org/2001/sw/rdb2rdf/directGraph/">http://www.w3.org/2001/sw/rdb2rdf/directGraph/</loc>
    </prevlocs>
    <latestloc>
      <loc href="http://www.w3.org/2001/sw/rdb2rdf/directGraph/">http://www.w3.org/2001/sw/rdb2rdf/directGraph/</loc>
    </latestloc>
    <authlist>
      <author role="Editor">
	<name>Eric Prud'hommeaux</name>
	<affiliation>W3C</affiliation>
	<email href="mailto:eric@w3.org">eric@w3.org</email>
      </author>
    </authlist>
    <abstract>
      <p>
The need to share data with collaborators motivates custodians and users of relational databases (RDB) to expose relational data on the Web of Data.
This document defines a very simple <em>direct mapping</em> from relational data to RDF.
This definition provides extension points for refinements within and outside of this document.
      </p>
    </abstract>
    <status>
      <p>
	<em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/">W3C technical reports index</a> at http://www.w3.org/TR/.</em>
      </p>
      <p>This is a <a href="http://www.w3.org/2005/10/Process-20051014/tr.html#RecsWD">Editors' Working Draft</a>.</p>
      <p>The documents produced by this Working Group are:</p>
      <ul>
	<li>RDB2RDF Mapping Language (R2RML) Specification</li>
	<li>RDB2RDF Mapping Language (R2RML) Conformance Tests</li>
      </ul>
      <p>This document was produced by a group operating under the <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 W3C Patent Policy</a>. W3C maintains a <a rel="disclosure" href="http://www.w3.org/2004/01/pp-impl/35463/status">public list of any patent disclosures</a> made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential Claim(s)</a> must disclose the information in accordance with <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section 6 of the W3C Patent Policy</a>.</p>
    </status>
    <languages>
      <language>en</language>
    </languages>
    <revisiondesc>
      <p>
	<emph>Last Modified: $Id: Overview.xml,v 1.60 2011/03/03 18:26:31 eric Exp $</emph>
      </p>
    </revisiondesc>
  </header>
  <body>
    <div1 id="intro">
      <head>Introduction</head>
      <p>
Relational databases proliferate both because of their efficiency and their precise definitions, allowing for tools like SQL <bibref ref="SQLFN"/> to manipulate and examine the contents predictably and efficiently.
Resource Description Framework (RDF) <bibref ref="RDF"/> is a data format based on a web-scalable architecture for identification and interpretation of terms.
This document defines a mapping from relational representation to an RDF representation.
      </p>
      <p>
Strategies for mapping relational data to RDF abound.
The <em>direct mapping</em> defines a simple transformation, providing a basis for defining and comparing more intricate transformations.
This document includes an informal and a formal description of the transformation<!-- , as well as a number of refinements intended both to meet use cases and establish a pattern for defing extensions -->.
      </p>

      <p>
The Direct Mapping is intended to provide a default behavior for <a href="http://www.w3.org/TR/2010/WD-r2rml-20101028/">R2RML: RDB to RDF Mapping Language</a>.
It can be also used to materialize RDF graphs or define virtual graphs, which can be queried by SPARQL or traversed by an RDF graph API.
      </p>
    </div1>
    <div1 id="emp-addr" note="#use">
      <head>Direct Mapping Description (Informative)</head>
      <p>
The direct mapping defines an <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-rdf-graph">RDF Graph</a> <bibref ref="RDF"/> represention of the data in any relational database.
The direct mapping takes as input a relational database (data and schema) generates an RDF graph is called the <em>direct graph</em> <!-- uniquely assigned to the database -->.
This graph is composed of relative IRIs and may be resolved against <em>base</em> URI per <bibref ref="RFC3987"/>
Foreign keys in relational databases establish a named reference from any row in a table to exactly one row in a (potentially different) table.
The direct graph conveys these references, as well as each value in the rows.
      </p>
      <div2 id="lead-ex">
      <head>Direct Mapping Example</head>
      <p>
The concepts in direct mapping can be introduced with an example RDF graph produced by a relational database.
	Following is SQL (DDL) to create a simple example with two tables with single-column primary keys and one foreign key reference between them:
      </p>
      <xsd>
CREATE TABLE Addresses (ID INT, city CHAR(10), state CHAR(2), PRIMARY KEY(ID))
CREATE TABLE People (ID INT, fname CHAR(10), addr INT, PRIMARY KEY(ID), FOREIGN KEY(addr) REFERENCES Addresses(ID))
INSERT INTO Addresses (ID, city, state) VALUES (18, "Cambridge", "MA")
INSERT INTO People (ID, fname, addr) VALUES (7, "Bob", 18)
INSERT INTO People (ID, fname, addr) VALUES (8, "Sue", NULL)
      </xsd>

      <p>
HTML tables will be used in this document to convey SQL tables.
The primary key of these tables will be marked with the <code class="pk">pk</code> class to convey an SQL primary key such as <code>ID</code> in <code>CREATE TABLE Addresses (ID INT, ... PRIMARY KEY(ID))</code>.
Foreign keys will be illustrated with a notation like "<code>→ Address(ID)</code>" to convey an SQL foreign key such as <code>CREATE TABLE People (... addr INT, FOREIGN KEY(addr) REFERENCES Addresses(ID))</code>.
      </p>

      <multicol>
	<table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	  <caption>People</caption>
	  <tbody>
	    <tr>
	      <th class="pk">PK</th>
	      <th colspan="1"></th>
	      <th>→ Address(ID)</th>
	    </tr>
	    <tr>
	      <th class="pk">ID</th>
	      <th>fname</th>
	      <th>addr</th>
	    </tr>
	    <tr>
	      <td onmouseover="hilight('emp-addr_t_7')"
		  onmouseout ="lolight('emp-addr_t_7')"
		  id="emp-addr_per7" class="pk">7</td>
	      <td onmouseover="hilight('emp-addr_t_Bob')"
		  onmouseout ="lolight('emp-addr_t_Bob')"
		  id="emp-addr_perBob">Bob</td>
	      <td onmouseover="hilight('emp-addr_t_ref18'); hilight('emp-addr_addr18')"
		  onmouseout ="lolight('emp-addr_t_ref18'); lolight('emp-addr_addr18')"
		  id="emp-addr_per18"><a href="#emp-addr_addr18">18</a></td>
	    </tr>
	    <tr>
	      <td onmouseover="hilight('emp-addr_t_8')"
		  onmouseout ="lolight('emp-addr_t_8')"
		  id="emp-addr_per8" class="pk">8</td>
	      <td onmouseover="hilight('emp-addr_t_Sue')"
		  onmouseout ="lolight('emp-addr_t_Sue')"
		  id="emp-addr_perSue" >Sue</td>
	      <td><em>NULL</em></td>
	    </tr>
	  </tbody>
	</table>
	<table class="right" cellpadding="2" cellspacing="0" border="1">
	  <caption>Addresses</caption>
	  <tbody>
	    <tr>
	      <th class="pk">PK</th>
	      <th colspan="2"></th>
	    </tr>
	    <tr>
	      <th class="pk">ID</th>
	      <th>city</th>
	      <th>state</th>
	    </tr>
	    <tr>
	      <td onmouseover="hilight('emp-addr_t_18')"
		  onmouseout ="lolight('emp-addr_t_18')"
		  id="emp-addr_addr18" class="pk">18</td>
	      <td onmouseover="hilight('emp-addr_t_Cambridge')"
		  onmouseout ="lolight('emp-addr_t_Cambridge')"
		  id="emp-addr_addrCamb">Cambridge</td>
	      <td onmouseover="hilight('emp-addr_t_MA')"
		  onmouseout ="lolight('emp-addr_t_MA')"
		  id="emp-addr_addrMA">MA</td>
	    </tr>
	  </tbody>
	</table>
      </multicol>
      <p class="clear">
Given a base of <code>http://foo.example/DB/</code> the direct mapping of this database produces a direct graph:
      </p>

      <turtle>
@base &lt;http://foo.example/DB/&gt;
@prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .

<triple onmouseover="hilight('emp-addr_per7')"
	onmouseout ="lolight('emp-addr_per7')"
	id="emp-addr_t_7"        >&lt;People/ID=7&gt; &lt;People#ID&gt; 7 .</triple>
<triple onmouseover="hilight('emp-addr_perBob')"
	onmouseout ="lolight('emp-addr_perBob')"
	id="emp-addr_t_Bob"      >&lt;People/ID=7&gt; &lt;People#fname&gt; "Bob" .</triple>
<triple onmouseover="hilight('emp-addr_per18')"
	onmouseout ="lolight('emp-addr_per18')"
	id="emp-addr_t_ref18"    >&lt;People/ID=7&gt; &lt;People#addr&gt; &lt;Addresses/ID=18&gt; .</triple>
<triple onmouseover="hilight('emp-addr_per8')"
	onmouseout ="lolight('emp-addr_per8')"
	id="emp-addr_t_8"        >&lt;People/ID=8&gt; &lt;People#ID&gt; 8 .</triple>
<triple onmouseover="hilight('emp-addr_perSue')"
	onmouseout ="lolight('emp-addr_perSue')"
	id="emp-addr_t_Sue"      >&lt;People/ID=8&gt; &lt;People#fname&gt; "Sue" .</triple>

<triple onmouseover="hilight('emp-addr_addr18')"
	onmouseout ="lolight('emp-addr_addr18')"
	id="emp-addr_t_18"       >&lt;Addresses/ID=18&gt; &lt;Addresses#ID&gt; 18 .</triple>
<triple onmouseover="hilight('emp-addr_addrCamb')"
	onmouseout ="lolight('emp-addr_addrCamb')"
	id="emp-addr_t_Cambridge">&lt;Addresses/ID=18&gt; &lt;Addresses#city&gt; "Cambridge" .</triple>
<triple onmouseover="hilight('emp-addr_addrMA')"
	onmouseout ="lolight('emp-addr_addrMA')"
	id="emp-addr_t_MA"       >&lt;Addresses/ID=18&gt; &lt;Addresses#state&gt; "MA" .</triple>
      </turtle>
      <p>
In this expression, each row, e.g. <code>(7, "Bob", 18)</code>, produces a set of triples with a common subject.
The subject is an IRI formed from the concatenation of the base, table name (<code>People</code>), primary key column name (<code>ID</code>) and primary key value (<code>7</code>).
The predicate for each column is an IRI formed from the concatenation of the base, table name and the column name.
The values are either RDF literals formed from the lexical form of the column value, or, in the case of foreign keys, row identifiers (<code>&lt;http://foo.example/DB/Addresses/ID=18&gt;</code>).
Note that these reference row identifiers must coincide with the subject used for the triples generated from the referenced row.
      </p>


      <!-- div3 id="use">
	<head>Use of the Direct Mapping</head>
	<p>
The Direct Mapping is intended to provide a default behavior for <a href="http://www.w3.org/TR/2010/WD-r2rml-20101028/">R2RML: RDB to RDF Mapping Language</a>.
It can be also used to materialize RDF graphs, such as the one above, or define virtual graphs, which can be queried by SPARQL or traversed by an RDF graph API.
When used to define a virtual graph, SPARQL queries over that virtual graph (below, left) may be executed as SQL queries (below, right), and the results transformed to RDF terms and return as <a href="http://www.w3.org/TR/rdf-sparql-XMLres/">SPARQL results</a>.
	</p>
	  <multicol>
	    <turtle class="nonRight">
PREFIX People: &lt;http://foo.example/DB/People#&gt;
PREFIX Addresses: &lt;http://foo.example/DB/Addresses#&gt;
SELECT ?name ?city WHERE {
    <triple onmouseover="hilight('emp-addr_t_Bob')"
	    onmouseout ="lolight('emp-addr_t_Bob')"
	    id="emp-addr_t_Bob">?who People:fname &lt;?name&gt; .</triple>
    <triple onmouseover="hilight('emp-addr_t_ref18')"
	    onmouseout ="lolight('emp-addr_t_ref18')"
	    id="emp-addr_q_ref18">?who People:addr ?address .</triple>
    <triple onmouseover="hilight('emp-addr_t_Cambridge')"
	    onmouseout ="lolight('emp-addr_t_Cambridge')"
	    id="emp-addr_q_Cambridge">?address People:city ?city .</triple>
 }
	    </turtle>
	    <sql class="nonRight">
&#x2d;&#x2d; SQL capturing the SPARQL query's graph constraints.
SELECT People.fname AS name, Addresses.city
  FROM People
  JOIN Addresses
       ON Addresses.ID=People.addr
 WHERE People.fname IS NOT NULL
   AND Addresses.city IS NOT NULL
	    </sql><div class="right"/>
	  </multicol>
      </div3 -->

      </div2>

      <div2 id="rules">
	<head>Mapping Rules</head>
	<p>
	  Each row in the database produces a set of <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-rdf-triple">RDF triples</a> with a <em>subject</em>, <em>predicate</em>, and <em>object</em> composed as follows:
	</p>

	<ulist>
	  <item>
	    shared <em>subject</em> — The single, unique <em>row identifier</em> may be a an IRI or a Blank Node.
	    If the table has no primary key, this subject is an <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-blank-node">RDF Blank Node</a>.
	    Otherwise, the subject is a <a href="#rowIRI">row IRI</a> (described below) composed of the base, table name and column name and value for each column in the primary key.
	  </item>
	  <item>
	    <em id="reference_triple">reference triples</em> — Each non-NULL foreign key generates a triple with the shared subject and a:
	    <ulist>
	      <item><em>predicate</em> — a <a href="#propertyIRI">property IRI</a> (described below) composed of the base, table name and column name for each column in the foreign key.</item>
	      <item><em>object</em> — the row identifier created for the referenced row.</item>
	    </ulist>
	  </item>
	  <item>
	    <em id="literal_triple">literal triples</em> — Each non-NULL column value generates a triple with a:
	    <ulist>
	      <item><em>predicate</em> — a property IRI composed of the base, table name and column name.</item>
	      <item><em>object</em> — an <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-literal">RDF Literal</a> with an XML Schema datatype corresponding to the SQL datatype of that value. Per <a href="#XMLdt">XML Datatypes for SQL Datatypes</a>, string datatypes are expressed as an <a href="http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal">RDF plain literal</a>.</item>
	    </ulist>
	    <em>Single-column foreign key</em> — Columns which are also the sole column in a foreign key do not generate a <a href="#literal_triple">literal triple</a>.
	    (Otherwise, there would be two values for that predicate, which may be single-valued/functional.)
	  </item>
	</ulist>

	<p>
The direct mapping generates relative IRIs; the examples in this document are resolved against a <em>base</em> IRI of <code>http://foo.example/DB/</code>.
There are two kinds of IRI composed for the direct mapping: property IRI and row IRI:
	</p>
	<ulist>
	  <item>
	    <em id="propertyIRI">property IRI</em> — IRIs in the predicate position are composed by concatenating:
	    <ulist>
	      <item>the <a href="http://www.w3.org/TR/wsdl#_http:urlEncoded">url-encoded</a> (per WSDL urlEncoded <bibref ref="WSDL"/>) table name</item>
	      <item>'#'</item>
	      <item>the url-encoded column names, separated by a ','</item>
	    </ulist>
	    For example, a table called <code>People</code> with a foreign key with the column names <code>fname, lname</code> would produce the IRI <code>&lt;http://foo.example/DB/People#fname,lname&gt;</code>
	  </item>
	  <item>
	    <em id="rowIRI">row IRI</em> — IRIs in the subject or object position include row values, and are composed by concatenating:
	    <ulist>
	      <item>the url-encoded table name</item>
	      <item>'/'</item>
	      <item>the pairs of url-encoded column name '=' url-encoded column value, separated by a ','. The column value is the lexical value per SQL 2008 Foundation <bibref ref="SQLFN"/>.</item>
	    </ulist>
	    For example, a row in a table called <code>People</code> with a primary key with the column names <code>fname, lname</code> with values <code>Bob Smith</code> would produce the IRI <code>&lt;http://foo.example/DB/People/fname=Bob,lname=Smith&gt;</code>
	  </item>
	</ulist>
      </div2>

      <div2 id="multi-key">
	<head>Multi-column Keys</head>
	<p>
More complex schemas include compound and composite primary keys<!-- and potentially incomplete foreign keys -->.
<!-- SQL foreign keys reference primary or candidate keys in the referenced relations. -->
In this example, the columns <em>deptName</em> and <em>deptCity</em> in the <em>People</em> table reference <em>name</em> and <em>city</em> in the <em>Department</em> table:
	</p>
	<multicol>
	  <table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	    <caption>People</caption>
	    <tbody>
	      <tr>
		<th class="pk">PK</th>
		<th colspan="2"></th>
		<th colspan="2">→ Department(name, city)</th>
	      </tr>
	      <tr>
		<th class="pk">ID</th>
		<th>fname</th>
		<th>addr</th>
		<th>deptName</th>
		<th>deptCity</th>
	      </tr>
	      <tr>
		<td onmouseover="hilight('multi-key_t_7');"
		    onmouseout ="lolight('multi-key_t_7');"
		    id="multi-key_per7" class="pk">7</td>
		<td onmouseover="hilight('multi-key_t_Bob');"
		    onmouseout ="lolight('multi-key_t_Bob');"
		    id="multi-key_perBob">Bob</td>
		<td onmouseover="hilight('multi-key_t_ref18'); hilight('multi-key_addr18')"
		    onmouseout ="lolight('multi-key_t_ref18'); lolight('multi-key_addr18')"
		    id="multi-key_per18"><a href="#multi-key_addr18">18</a></td>
		<td onmouseover="hilight('multi-key_t_refaccounting'); hilight('multi-key_t_refaccCa'); hilight('multi-key_deptacc');"
		    onmouseout ="lolight('multi-key_t_refaccounting'); lolight('multi-key_t_refaccCa'); lolight('multi-key_deptacc');"
		    id="multi-key_peraccounting"><a href="#multi-key_deptacc">accounting</a></td>
		<td onmouseover="hilight('multi-key_t_refCambridge'); hilight('multi-key_t_refaccCa'); hilight('multi-key_deptCam')"
		    onmouseout ="lolight('multi-key_t_refCambridge'); lolight('multi-key_t_refaccCa'); lolight('multi-key_deptCam')"
		    id="multi-key_perCambridge"><a href="#multi-key_deptCam">Cambridge</a></td>
	      </tr>
	      <tr>
		<td onmouseover="hilight('multi-key_t_8');"
		    onmouseout ="lolight('multi-key_t_8');"
		    id="multi-key_per8" class="pk"><a id="multi-key_per8">8</a></td>
		<td onmouseover="hilight('multi-key_t_Sue');"
		    onmouseout ="lolight('multi-key_t_Sue');"
		    id="multi-key_perSue">Sue</td>
		<td><em>NULL</em></td>
		<td><em>NULL</em></td>
		<td><em>NULL</em></td>
	      </tr>
	    </tbody>
	  </table>
	  <table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	    <caption>Addresses</caption>
	    <tbody>
	      <tr>
		<th class="pk">PK</th>
		<th colspan="2"></th>
	      </tr>
	      <tr>
		<th class="pk">ID</th>
		<th>city</th>
		<th>state</th>
	      </tr>
	      <tr>
		<td onmouseover="hilight('multi-key_t_18');"
		    onmouseout ="lolight('multi-key_t_18');"
		    id="multi-key_addr18" class="pk">18</td>
		<td onmouseover="hilight('multi-key_t_Cambridge');"
		    onmouseout ="lolight('multi-key_t_Cambridge');"
		    id="multi-key_addrCamb">Cambridge</td>
		<td onmouseover="hilight('multi-key_t_MA');"
		    onmouseout ="lolight('multi-key_t_MA');"
		    id="multi-key_addrMA">MA</td>
	      </tr>
	    </tbody>
	  </table>
	  <table class="right" cellpadding="2" cellspacing="0" border="1">
	    <caption>Department</caption>
	    <tbody>
	      <tr>
		<th class="pk">PK</th>
		<th colspan="2">Unique key</th>
		<th></th>
	      </tr>
	      <tr>
		<th class="pk">ID</th>
		<th>name</th>
		<th>city</th>
		<th>manager</th>
	      </tr>
	      <tr>
		<td onmouseover="hilight('multi-key_t_23');"
		    onmouseout ="lolight('multi-key_t_23');"
		    id="multi-key_dept23" class="pk">23</td>
		<td onmouseover="hilight('multi-key_t_accounting');"
		    onmouseout ="lolight('multi-key_t_accounting');"
		    id="multi-key_deptacc">accounting</td>
		<td onmouseover="hilight('multi-key_t_DeptCam');"
		    onmouseout ="lolight('multi-key_t_DeptCam');"
		    id="multi-key_deptCam">Cambridge</td>
		<td onmouseover="hilight('multi-key_t_ref8'); hilight('multi-key_per8')"
		    onmouseout ="lolight('multi-key_t_ref8'); lolight('multi-key_per8')"
		    id="multi-key_dept8"><a href="#multi-key_per8">8</a></td>
	      </tr>
	    </tbody>
	  </table>
	</multicol>
	<p>
Per the People tables's compound foreign key to Department:
	</p>
	<ulist>
	  <item>
The row in <em>People</em> with <code>deptName="accounting"</code> and <code>deptCity="Cambridge"</code> references a row in <em>Department</em> with a primary key of <code>ID=23</code>.
	  </item>
	  <item>
The predicate for this key is formed from "<code>deptName,deptCity</code>", reflecting the order of the column names in the foreign key.
	  </item>
	  <item>
The referent identifier (object of the above predicate) is formed from the base and "<code>ID=23</code>".
	  </item>
	</ulist>
	<turtle>
@base &lt;http://foo.example/DB/&gt;
@prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .

<triple onmouseover="hilight('multi-key_per7')"
	onmouseout ="lolight('multi-key_per7')"
	id="multi-key_t_7">&lt;People/ID=7&gt; &lt;People#ID&gt; 7 .</triple>
<triple onmouseover="hilight('multi-key_perBob')"
	onmouseout ="lolight('multi-key_perBob')"
	id="multi-key_t_Bob">&lt;People/ID=7&gt; &lt;People#fname&gt; "Bob" .</triple>
<triple onmouseover="hilight('multi-key_per18')"
	onmouseout ="lolight('multi-key_per18')"
	id="multi-key_t_ref18">&lt;People/ID=7&gt; &lt;People#addr&gt; &lt;Addresses/ID=18&gt; .</triple>
<triple onmouseover="hilight('multi-key_peraccounting')"
	onmouseout ="lolight('multi-key_peraccounting')"
	id="multi-key_t_refaccounting" class="new">&lt;People/ID=7&gt; &lt;People#deptName&gt; "accounting" .</triple>
<triple onmouseover="hilight('multi-key_perCambridge')"
	onmouseout ="lolight('multi-key_perCambridge')"
	id="multi-key_t_refCambridge" class="new">&lt;People/ID=7&gt; &lt;People#deptCity&gt; "Cambridge" .</triple>
<triple onmouseover="hilight('multi-key_peraccounting'); hilight('multi-key_perCambridge')"
	onmouseout ="lolight('multi-key_peraccounting'); lolight('multi-key_perCambridge')"
	id="multi-key_t_refaccCa" class="new">&lt;People/ID=7&gt; &lt;People#deptName,deptCity&gt; &lt;Department/ID=23&gt; .</triple>
<triple onmouseover="hilight('multi-key_per8')"
	onmouseout ="lolight('multi-key_per8')"
	id="multi-key_t_8">&lt;People/ID=8&gt; &lt;People#ID&gt; 8 .</triple>
<triple onmouseover="hilight('multi-key_perSue')"
	onmouseout ="lolight('multi-key_perSue')"
	id="multi-key_t_Sue">&lt;People/ID=8&gt; &lt;People#fname&gt; "Sue" .</triple>

<triple onmouseover="hilight('multi-key_addr18')"
	onmouseout ="lolight('multi-key_addr18')"
	id="multi-key_t_18">&lt;Addresses/ID=18&gt; &lt;Addresses#ID&gt; 18 .</triple>
<triple onmouseover="hilight('multi-key_addrCamb')"
	onmouseout ="lolight('multi-key_addrCamb')"
	id="multi-key_t_Cambridge">&lt;Addresses/ID=18&gt; &lt;Addresses#city&gt; "Cambridge" .</triple>
<triple onmouseover="hilight('multi-key_addrMA')"
	onmouseout ="lolight('multi-key_addrMA')"
	id="multi-key_t_MA">&lt;Addresses/ID=18&gt; &lt;Addresses#state&gt; "MA" .</triple>

<triple onmouseover="hilight('multi-key_dept23');"
	onmouseout ="lolight('multi-key_dept23');"
	id="multi-key_t_23" class="new">&lt;Department/ID=23&gt; &lt;Department#ID&gt; 23 .</triple>
<triple onmouseover="hilight('multi-key_deptacc');"
	onmouseout ="lolight('multi-key_deptacc');"
	id="multi-key_t_accounting" class="new">&lt;Department/ID=23&gt; &lt;Department#name&gt; "accounting" .</triple>
<triple onmouseover="hilight('multi-key_deptCam');"
	onmouseout ="lolight('multi-key_deptCam');"
	id="multi-key_t_DeptCam" class="new">&lt;Department/ID=23&gt; &lt;Department#city&gt; "Cambridge" .</triple>
<triple onmouseover="hilight('multi-key_dept8');"
	onmouseout ="lolight('multi-key_dept8');"
	id="multi-key_t_ref8" class="new">&lt;Department/ID=23&gt; &lt;Department#manager&gt; &lt;People#ID=8&gt; .</triple>
	</turtle>
	<p>
Primary keys may also be composite. If the primary key for <em>Department</em> were (<em>name</em>, <em>city</em>), the identifier for that first (only) row would be <code>&lt;http://foo.example/DB/Department/name.Accounting,city.Cambridge&gt;</code>.
	</p>
      </div2>

      <div2 id="no-pk">
	<head>Empty (Non-existent) Primary Keys</head>
	<p>
Even if there is no primary key, rows generate a set of triples with a shared subject, but that subject is a blank node:
	</p>
	<multicol>
	  <table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	    <caption>Tweets</caption>
	    <tbody>
	      <tr>
		<th colspan="1">→ People(ID)</th>
		<th colspan="2"></th>
	      </tr>
	      <tr>
		<th>tweeter</th>
		<th>when</th>
		<th>text</th>
	      </tr>
	      <tr>
		<td onmouseover="hilight('no-pk_t_a7')"
		    onmouseout ="lolight('no-pk_t_a7')"
		    id="no-pk_tweeta7" class="fk"><a href="#person7">7</a></td>
		<td onmouseover="hilight('no-pk_t_adt')"
		    onmouseout ="lolight('no-pk_t_adt')"
		    id="no-pk_tweetadt">2010-08-30T01:33</td>
		<td onmouseover="hilight('no-pk_t_atext')"
		    onmouseout ="lolight('no-pk_t_atext')"
		    id="no-pk_tweetatext">I really like lolcats.</td>
	      </tr>
	      <tr>
		<td onmouseover="hilight('no-pk_t_b7')"
		    onmouseout ="lolight('no-pk_t_b7')"
		    id="no-pk_tweetb7" class="fk"><a href="#person7">7</a></td>
		<td onmouseover="hilight('no-pk_t_bdt')"
		    onmouseout ="lolight('no-pk_t_bdt')"
		    id="no-pk_tweetbdt">2010-08-30T09:01</td>
		<td onmouseover="hilight('no-pk_t_btext')"
		    onmouseout ="lolight('no-pk_t_btext')"
		    id="no-pk_tweetbtext">I take it back.</td>
	      </tr>
	    </tbody>
	  </table>
	</multicol>
	<turtle>
@base &lt;http://foo.example/DB/&gt;
@prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .

<triple onmouseover="hilight('no-pk_tweeta7')"
	onmouseout ="lolight('no-pk_tweeta7')"
	id="no-pk_t_a7">_:a &lt;Tweets#tweeter&gt; &lt;People/ID=7&gt; .</triple>
<triple onmouseover="hilight('no-pk_tweetadt')"
	onmouseout ="lolight('no-pk_tweetadt')"
	id="no-pk_t_adt">_:a &lt;Tweets#when&gt; "2010-08-30T01:33"^^xsd:dateTime .</triple>
<triple onmouseover="hilight('no-pk_tweetatext')"
	onmouseout ="lolight('no-pk_tweetatext')"
	id="no-pk_t_atext">_:a &lt;Tweets#text&gt; "I really like lolcats." .</triple>

<triple onmouseover="hilight('no-pk_tweetb7')"
	onmouseout ="lolight('no-pk_tweetb7')"
	id="no-pk_t_b7">_:b &lt;Tweets#tweeter&gt; &lt;People/ID=7&gt; .</triple>
<triple onmouseover="hilight('no-pk_tweetbdt')"
	onmouseout ="lolight('no-pk_tweetbdt')"
	id="no-pk_t_bdt">_:b &lt;Tweets#when&gt; "2010-08-30T09:01"^^xsd:dateTime .</triple>
<triple onmouseover="hilight('no-pk_tweetbtext')"
	onmouseout ="lolight('no-pk_tweetbtext')"
	id="no-pk_t_btext">_:b &lt;Tweets#text&gt; "I take it back." .</triple>
	</turtle>
	<p>
It is not possible to dereference blank nodes ("_:a" and "_:b" above).
Queries or updates may be made to these nodes via SPARQL queries.
	</p>

	<div3 id="ref-no-pk">
	  <head>Referencing Tables with Empty Primary Keys</head>
	  <p>
Rows in tables with no primary key may still be refrenced by foreign keys.
(Relational theory tells us that these rows must be unique as foreign keys reference candidate keys and candidate keys are unique across all the rows in a table.)
References to rows in tables with no primary key are expressed as RDF triples with blank nodes for objects, where that blank node is the same node used for the subject in the referenced row.
	  </p>
	  <p>
This example includes several foreign keys with mutual column names.
For clarity; here is the DDL to clarify these keys:
	  </p>
	  <xsd>
CREATE TABLE Projects (lead INT,
                       FOREIGN KEY (lead) REFERENCES People(ID),
                       name VARCHAR(50), UNIQUE (lead, name), 
                       deptName VARCHAR(50), deptCity VARCHAR(50),
                       UNIQUE (name, deptName, deptCity),
                       FOREIGN KEY (deptName, deptCity) REFERENCES Department(name, city));
CREATE TABLE TaskAssignments (worker INT,
                              FOREIGN KEY (worker) REFERENCES People(ID),
                              project VARCHAR(50), PRIMARY KEY (worker, project), 
                              deptName VARCHAR(50), deptCity VARCHAR(50),
                              FOREIGN KEY (worker) REFERENCES People(ID),
                              FOREIGN KEY (project, deptName, deptCity) REFERENCES Projects(name, deptName, deptCity),
                              FOREIGN KEY (deptName, deptCity) REFERENCES Department(name, city));
	  </xsd>
	  <multicol>
	    <table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	      <caption>Projects</caption>
	      <tbody>
		<tr>
		  <th colspan="2">Unique key</th>
		  <th colspan="2"></th>
		</tr>
		<tr>
		  <th colspan="1"></th>
		  <th colspan="3">Unique key</th>
		</tr>
		<tr>
		  <th colspan="1">→ People(ID)</th>
		  <th colspan="1"></th>
		  <th colspan="2">→ Department(name, city)</th>
		</tr>
		<tr>
		  <th>lead</th>
		  <th>name</th>
		  <th>deptName</th>
		  <th>deptCity</th>
		</tr>
		<tr>
		  <td onmouseover="hilight('ref-no-pk_t_c8');"
		      onmouseout ="lolight('ref-no-pk_t_c8');"
		      id="ref-no-pk_projc8" class="fk"><a href="#person8">8</a></td>
		  <td onmouseover="hilight('ref-no-pk_t_cpencil');"
		      onmouseout ="lolight('ref-no-pk_t_cpencil');"
		      id="ref-no-pk_projcpencil">pencil survey</td>
		  <td onmouseover="hilight('ref-no-pk_t_cacc');hilight('ref-no-pk_t_c23')"
		      onmouseout ="lolight('ref-no-pk_t_cacc');lolight('ref-no-pk_t_c23')"
		      id="ref-no-pk_projcacc">accounting</td>
		  <td onmouseover="hilight('ref-no-pk_t_cCam');hilight('ref-no-pk_t_c23')"
		      onmouseout ="lolight('ref-no-pk_t_cCam');lolight('ref-no-pk_t_c23')"
		      id="ref-no-pk_projcCam">Cambridge</td>
		</tr>
		<tr>
		  <td onmouseover="hilight('ref-no-pk_t_d8');"
		      onmouseout ="lolight('ref-no-pk_t_d8');"
		      id="ref-no-pk_projd8" class="fk"><a href="#person7">8</a></td>
		  <td onmouseover="hilight('ref-no-pk_t_deraser');"
		      onmouseout ="lolight('ref-no-pk_t_deraser');"
		      id="ref-no-pk_projderaser">eraser survey</td>
		  <td onmouseover="hilight('ref-no-pk_t_dacc');hilight('ref-no-pk_t_d23')"
		      onmouseout ="lolight('ref-no-pk_t_dacc');lolight('ref-no-pk_t_d23')"
		      id="ref-no-pk_projdacc">accounting</td>
		  <td onmouseover="hilight('ref-no-pk_t_dCam');hilight('ref-no-pk_t_d23')"
		      onmouseout ="lolight('ref-no-pk_t_dCam');lolight('ref-no-pk_t_d23')"
		      id="ref-no-pk_projdCam">Cambridge</td>
		</tr>
	      </tbody>
	    </table>
	    <table class="right" cellpadding="2" cellspacing="0" border="1">
	      <caption>TaskAssignments</caption>
	      <tbody>
		<tr>
		  <th colspan="2" class="pk">PK</th>
		  <th colspan="2"></th>
		</tr>
		<tr>
		  <th></th>
		  <th colspan="3">→ Projects(name, deptName, deptCity)</th>
		</tr>
		<tr>
		  <th>→ People(ID)</th>
		  <th colspan="1"></th>
		  <th colspan="2">→ Departments(name, city)</th>
		</tr>
		<tr>
		  <th class="pk">worker</th>
		  <th class="pk">project</th>
		  <th>deptName</th>
		  <th>deptCity</th>
		</tr>
		<tr>
		  <td onmouseover="hilight('ref-no-pk_t_pencil7')"
		      onmouseout ="lolight('ref-no-pk_t_pencil7')"
		      id="ref-no-pk_ta7" class="pk"><a href="#person7">7</a></td>
		  <td onmouseover="hilight('ref-no-pk_t_pencilpencil');hilight('ref-no-pk_t_pencilc');hilight('ref-no-pk_projcpencil')"
		      onmouseout ="lolight('ref-no-pk_t_pencilpencil');lolight('ref-no-pk_t_pencilc');lolight('ref-no-pk_projcpencil')"
		      id="ref-no-pk_tapencil" class="pk">pencil survey</td>
		  <td onmouseover="hilight('ref-no-pk_t_pencilacc');hilight('ref-no-pk_t_pencilc');hilight('ref-no-pk_t_pencil23');hilight('ref-no-pk_projcacc')"
		      onmouseout ="lolight('ref-no-pk_t_pencilacc');lolight('ref-no-pk_t_pencilc');lolight('ref-no-pk_t_pencil23');lolight('ref-no-pk_projcacc')"
		      id="ref-no-pk_taacc">accounting</td>
		  <td onmouseover="hilight('ref-no-pk_t_pencilCam');hilight('ref-no-pk_t_pencilc');hilight('ref-no-pk_t_pencil23');hilight('ref-no-pk_projcCam')"
		      onmouseout ="lolight('ref-no-pk_t_pencilCam');lolight('ref-no-pk_t_pencilc');lolight('ref-no-pk_t_pencil23');lolight('ref-no-pk_projcCam')"
		      id="ref-no-pk_taCam">Cambridge</td>
		</tr>
	      </tbody>
	    </table>
	  </multicol>
	  <turtle>
@base &lt;http://foo.example/DB/&gt;
@prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .
@prefix pencil: &lt;http://foo.example/DB/TaskAssignment/worker=7_project=pencil+survey#&gt;

<triple onmouseover="hilight('ref-no-pk_projc8')"
	onmouseout ="lolight('ref-no-pk_projc8')"
	id="ref-no-pk_t_c8">_:c &lt;Projects#lead&gt; &lt;People/ID=8&gt; .</triple>
<triple onmouseover="hilight('ref-no-pk_projcpencil')"
	onmouseout ="lolight('ref-no-pk_projcpencil')"
	id="ref-no-pk_t_cpencil">_:c &lt;Projects#name&gt; "pencil survey" .</triple>
<triple onmouseover="hilight('ref-no-pk_projcacc')"
	onmouseout ="lolight('ref-no-pk_projcacc')"
	id="ref-no-pk_t_cacc">_:c &lt;Projects#deptName&gt; "accounting" .</triple>
<triple onmouseover="hilight('ref-no-pk_projcCam')"
	onmouseout ="lolight('ref-no-pk_projcCam')"
	id="ref-no-pk_t_cCam">_:c &lt;Projects#deptCity&gt; "Cambridge" .</triple>
<triple onmouseover="hilight('ref-no-pk_projcacc'); hilight('ref-no-pk_projcCam')"
	onmouseout ="lolight('ref-no-pk_projcacc'); lolight('ref-no-pk_projcCam')"
	id="ref-no-pk_t_c23">_:c &lt;Projects#deptName,deptCity&gt; &lt;Department/ID=23&gt; .</triple>

<triple onmouseover="hilight('ref-no-pk_projd8')"
	onmouseout ="lolight('ref-no-pk_projd8')"
	id="ref-no-pk_t_d8">_:d &lt;Projects#lead&gt; &lt;People/ID=8&gt; .</triple>
<triple onmouseover="hilight('ref-no-pk_projderaser')"
	onmouseout ="lolight('ref-no-pk_projderaser')"
	id="ref-no-pk_t_deraser">_:d &lt;Projects#name&gt; "eraser survey" .</triple>
<triple onmouseover="hilight('ref-no-pk_projdacc')"
	onmouseout ="lolight('ref-no-pk_projdacc')"
	id="ref-no-pk_t_dacc">_:d &lt;Projects#deptName&gt; "accounting" .</triple>
<triple onmouseover="hilight('ref-no-pk_projdCam')"
	onmouseout ="lolight('ref-no-pk_projdCam')"
	id="ref-no-pk_t_dCam">_:d &lt;Projects#deptCity&gt; "Cambridge" .</triple>
<triple onmouseover="hilight('ref-no-pk_projdacc'); hilight('ref-no-pk_projdCam')"
	onmouseout ="lolight('ref-no-pk_projdacc'); lolight('ref-no-pk_projdCam')"
	id="ref-no-pk_t_d23">_:d &lt;Projects#deptName,deptCity&gt; &lt;Department/ID=23&gt; .</triple>

<triple onmouseover="hilight('ref-no-pk_ta7')"
	onmouseout ="lolight('ref-no-pk_ta7')"
	id="ref-no-pk_t_pencil7">pencil:_ &lt;TaskAssignments#worker&gt; &lt;People/ID=7&gt; .</triple>
<triple onmouseover="hilight('ref-no-pk_tapencil')"
	onmouseout ="lolight('ref-no-pk_tapencil')"
	id="ref-no-pk_t_pencilpencil">pencil:_ &lt;TaskAssignments#project&gt; "pencil survey" .</triple>
<triple onmouseover="hilight('ref-no-pk_taacc')"
	onmouseout ="lolight('ref-no-pk_taacc')"
	id="ref-no-pk_t_pencilacc">pencil:_ &lt;TaskAssignments#deptName&gt; "accounting" .</triple>
<triple onmouseover="hilight('ref-no-pk_taCam')"
	onmouseout ="lolight('ref-no-pk_taCam')"
	id="ref-no-pk_t_pencilCam">pencil:_ &lt;TaskAssignments#deptCity&gt; "Cambridge" .</triple>
<triple onmouseover="hilight('ref-no-pk_taacc');hilight('ref-no-pk_taCam')"
	onmouseout ="lolight('ref-no-pk_taacc');lolight('ref-no-pk_taCam')"
	id="ref-no-pk_t_pencil23">pencil:_ &lt;TaskAssignments#deptName,deptCity&gt; &lt;Department/ID=23&gt; .</triple>
<triple onmouseover="hilight('ref-no-pk_tapencil');hilight('ref-no-pk_taacc');hilight('ref-no-pk_taCam')"
	onmouseout ="lolight('ref-no-pk_tapencil');lolight('ref-no-pk_taacc');lolight('ref-no-pk_taCam')"
	id="ref-no-pk_t_pencilc" class="new">pencil:_ &lt;TaskAssignments#project,deptName,deptCity&gt; _:c .</triple>
	  </turtle>
	  <p>
The absence of a primary key forces the generation of blank nodes, but does not change the structure of the direct graph or names of the predicates in that graph.
<!-- This example SPARQL query would find the leads for <em>Person</em> 7's projects regardless of whether the <em>Projects</em> table had a primary key or not.
The following SPARQL query show how the graph constraints might be captured in an RDF query; the SQL query shows how it might be executed as SQL: -->
	  </p>
<!--
	  <multicol>
	    <turtle class="nonRight">
PREFIX asgn: &lt;http://foo.example/DB/TaskAssignments#&gt;
PREFIX proj: &lt;http://foo.example/DB/Projects#&gt;
SELECT ?lead
 <triple onmouseover="hilight('ref-no-pk_t_pencil7');hilight('ref-no-pk_t_pencilc');hilight('ref-no-pk_t_c8');hilight('ref-no-pk_q_pencil7');hilight('ref-no-pk_q_pencilc');hilight('ref-no-pk_q_c8')"
	 onmouseout ="lolight('ref-no-pk_t_pencil7');lolight('ref-no-pk_t_pencilc');lolight('ref-no-pk_t_c8');lolight('ref-no-pk_q_pencil7');lolight('ref-no-pk_q_pencilc');lolight('ref-no-pk_q_c8')"
	 id="ref-no-pk_q_where">WHERE</triple> {
    <triple onmouseover="hilight('ref-no-pk_t_pencil7')"
	    onmouseout ="lolight('ref-no-pk_t_pencil7')"
	    id="ref-no-pk_q_pencil7">?assignment asgn:worker &lt;http://foo.example/DB/People/ID=7&gt; .</triple>
    <triple onmouseover="hilight('ref-no-pk_t_pencilc')"
	    onmouseout ="lolight('ref-no-pk_t_pencilc')"
	    id="ref-no-pk_q_pencilc">?assignment asgn:project,deptName,deptCity ?project .</triple>
    <triple onmouseover="hilight('ref-no-pk_t_c8')"
	    onmouseout ="lolight('ref-no-pk_t_c8')"
	    id="ref-no-pk_q_c8">?project proj:lead ?lead .</triple>
 }
	    </turtle>
	    <sql class="nonRight">
&#x2d;&#x2d; SQL capturing the SPARQL query's graph constraints.
SELECT lead
FROM TaskAssignments
JOIN Projects ON
      Projects.project=TaskAssignments.name
  AND Projects.deptName=TaskAssignments.deptName
  AND Projects.deptCity=TaskAssignments.deptCity
WHERE Projects.worker=7
	    </sql><div class="right"/>
	  </multicol>
-->
	</div3>

      </div2>


      <!-- div2 id="hier-tabl">
	<head>Hierarchical Tables</head>
	<p>
It is common to express specializations of some concept as mutiple tables sharing a common primkary key.
In such cases, the primary keys of the inherited tables are in turn foreign keys to the tabel from which they derive.
	</p>
	<multicol>
	  <!-!-  table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	    <caption>People</caption>
	    <tbody>
	      <tr>
		<th class="pk">PK</th>
		<th colspan="2"></th>
	      </tr>
	      <tr>
		<th class="pk">ID</th>
		<th>fname</th>
		<th>addr</th>
	      </tr>
	      <tr>
		<td onmouseover="hilight('hier-tabl_t_7');"
		    onmouseout ="lolight('hier-tabl_t_7');"
		    id="hier-tabl_per7" class="pk"><a id="person7">7</a></td>
		<td onmouseover="hilight('hier-tabl_t_Bob');"
		    onmouseout ="lolight('hier-tabl_t_Bob');"
		    id="hier-tabl_perBob">Bob</td>
		<td onmouseover="hilight('hier-tabl_t_ref18'); hilight('hier-tabl_addr18')"
		    onmouseout ="lolight('hier-tabl_t_ref18'); lolight('hier-tabl_addr18')"
		    id="hier-tabl_per18"><a href="#hier-tabl_addr18">18</a></td>
	      </tr>
	    </tbody>
	  </table -!->
	  <table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	    <caption>Addresses</caption>
	    <tbody>
	      <tr>
		<th class="pk">PK</th>
		<th colspan="2"></th>
	      </tr>
	      <tr>
		<th class="pk">ID</th>
		<th>city</th>
		<th>state</th>
	      </tr>
	      <tr>
		<td onmouseover="hilight('hier-tabl_t_18');"
		    onmouseout ="lolight('hier-tabl_t_18');"
		    id="hier-tabl_addr18" class="pk">18</td>
		<td onmouseover="hilight('hier-tabl_t_Cambridge');"
		    onmouseout ="lolight('hier-tabl_t_Cambridge');"
		    id="hier-tabl_addrCamb">Cambridge</td>
		<td onmouseover="hilight('hier-tabl_t_MA');"
		    onmouseout ="lolight('hier-tabl_t_MA');"
		    id="hier-tabl_addrMA">MA</td>
	      </tr>
	    </tbody>
	  </table>
	  <table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	    <caption>Offices</caption>
	    <tbody>
	      <tr>
		<th class="pk">PK</th>
		<th colspan="2"></th>
	      </tr>
	      <tr>
		<th>→ Addresses(ID)</th>
		<th colspan="2"></th>
	      </tr>
	      <tr>
		<th class="pk">ID</th>
		<th>building</th>
		<th>ofcNumber</th>
	      </tr>
	      <tr>
		<td onmouseover="hilight('hier-tabl_t_offc18'); hilight('hier-tabl_addr18')"
		    onmouseout ="lolight('hier-tabl_t_offc18'); lolight('hier-tabl_addr18')"
		    id="hier-tabl_offc18" class="pk"><a href="#hier-tabl_addr18">18</a></td>
		<td onmouseover="hilight('hier-tabl_t_offc32');"
		    onmouseout ="lolight('hier-tabl_t_offc32');"
		    id="hier-tabl_offc32">32</td>
		<td onmouseover="hilight('hier-tabl_t_offcG528');"
		    onmouseout ="lolight('hier-tabl_t_offcG528');"
		    id="hier-tabl_offcG528">G528</td>
	      </tr>
	    </tbody>
	  </table>
	  <table class="right" cellpadding="2" cellspacing="0" border="1">
	    <caption>ExecutiveOffices</caption>
	    <tbody>
	      <tr>
		<th class="pk">PK</th>
		<th colspan="1"></th>
	      </tr>
	      <tr>
		<th>→ Offices(ID)</th>
		<th colspan="1"></th>
	      </tr>
	      <tr>
		<th class="pk">ID</th>
		<th>desk</th>
	      </tr>
	      <tr>
		<td onmouseover="hilight('hier-tabl_t_exec18'); hilight('hier-tabl_addr18')"
		    onmouseout ="lolight('hier-tabl_t_exec18'); lolight('hier-tabl_addr18')"
		    id="hier-tabl_exec18" class="pk"><a href="#hier-tabl_addr18">18</a></td>
		<td onmouseover="hilight('hier-tabl_t_execoak');"
		    onmouseout ="lolight('hier-tabl_t_execoak');"
		    id="hier-tabl_execoak">oak</td>
	      </tr>
	    </tbody>
	  </table>
	</multicol>
	<p>
In this example, <em>Offices</em> are a specialization of <em>Addresses</em> and <em>ExecutiveOffices</em> are a specialization of <em>Offices</em>.
The subjects for the triples implied by rows in <em>Offices</em> or <em>ExecutiveOffices</em> are the same as those for the corresponding row in <em>Addresses</em>.
	</p>
	<turtle>
@base &lt;http://foo.example/DB/&gt;
@prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .
<!-!- 
<triple onmouseover="hilight('hier-tabl_per7')"
	onmouseout ="lolight('hier-tabl_per7')"
	id="hier-tabl_t_7">&lt;People/ID=7&gt; &lt;People#ID&gt; 7 .</triple>
<triple onmouseover="hilight('hier-tabl_perBob')"
	onmouseout ="lolight('hier-tabl_perBob')"
	id="hier-tabl_t_Bob">&lt;People/ID=7&gt; &lt;People#fname&gt; "Bob" .</triple>
<triple onmouseover="hilight('hier-tabl_per18')"
	onmouseout ="lolight('hier-tabl_per18')"
	id="hier-tabl_t_ref18">&lt;People/ID=7&gt; &lt;People#addr&gt; &lt;Addresses/ID=18&gt; .</triple>
 -!->
<triple onmouseover="hilight('hier-tabl_addr18')"
	onmouseout ="lolight('hier-tabl_addr18')"
	id="hier-tabl_t_18">&lt;Addresses/ID=18&gt; &lt;Addresses#ID&gt; 18 .</triple>
<triple onmouseover="hilight('hier-tabl_addrCamb')"
	onmouseout ="lolight('hier-tabl_addrCamb')"
	id="hier-tabl_t_Cambridge">&lt;Addresses/ID=18&gt; &lt;Addresses#city&gt; "Cambridge" .</triple>
<triple onmouseover="hilight('hier-tabl_addrMA')"
	onmouseout ="lolight('hier-tabl_addrMA')"
	id="hier-tabl_t_MA">&lt;Addresses/ID=18&gt; &lt;Addresses#state&gt; "MA" .</triple>

<triple onmouseover="hilight('hier-tabl_offc18')"
	onmouseout ="lolight('hier-tabl_offc18')"
	id="hier-tabl_t_offc18" class="new">&lt;Addresses/ID=18&gt; &lt;Offices#ID&gt; 18 .</triple>
<triple onmouseover="hilight('hier-tabl_offc32')"
	onmouseout ="lolight('hier-tabl_offc32')"
	id="hier-tabl_t_offc32" class="new">&lt;Addresses/ID=18&gt; &lt;Offices#building&gt; 32 .</triple>
<triple onmouseover="hilight('hier-tabl_offcG528')"
	onmouseout ="lolight('hier-tabl_offcG528')"
	id="hier-tabl_t_offcG528" class="new">&lt;Addresses/ID=18&gt; &lt;Offices#ofcNumber&gt; "G528" .</triple>

<triple onmouseover="hilight('hier-tabl_exec18')"
	onmouseout ="lolight('hier-tabl_exec18')"
	id="hier-tabl_t_exec18" class="new">&lt;Addresses/ID=18&gt; &lt;ExecutiveOffices#ID&gt; 18 .</triple>
<triple onmouseover="hilight('hier-tabl_execoak')"
	onmouseout ="lolight('hier-tabl_execoak')"
	id="hier-tabl_t_execoak" class="new">&lt;Addresses/ID=18&gt; &lt;ExecutiveOffices#desk&gt; "oak" .</triple>
	</turtle>
	<p id="pfkexception"><em>Primary-is-Candidate-Key Exception</em>: If the primary key is also a candidate key K to table R:</p>
	<ulist>
	  <item>
	    The shared subject is the subject of the referenced row in R.
	  </item>
	  <item>
	    The foreign key K generates no reference triple.
	  </item>
	  <item>
	    Even if K is a single-column foreign key, it generates a literal triple.
	  </item>
	</ulist>
	<p>
	  Section 2.4 <a href="#hier-tabl">Hierarchical Tables</a> shows how this exception is applied.
	</p>
	<issue id="hier-table-at-risk">This feature attempts to intricately model some existing modeling practice but adds significant complexity. This feature is at risk.</issue>
	<p>
	  The <a href="#pfkexception">Primary-is-foreign Key Exception</a> allows the generation of a triple with an RDF literal for the <em>ID</em> column in the <em>Offices</em> and <em>ExecutiveOffices</em> table (<code onmouseover="hilight('hier-tabl_t_offc18'); hilight('hier-tabl_offc18')"
		 onmouseout ="lolight('hier-tabl_t_offc18'); lolight('hier-tabl_offc18')"
		 >Offices.ID=18</code> and <code onmouseover="hilight('hier-tabl_t_exec18'); hilight('hier-tabl_exec18')"
						 onmouseout ="lolight('hier-tabl_t_exec18'); lolight('hier-tabl_exec18')"
						 >ExecutiveOffices.ID=18</code>).
	</p>
	<issue id="fk-pk-order">What if fk is to a rearrangement of the pk? E.g what if TaskAssignments, with a primary key (project, worker), had a foreign key (worker, project)?</issue>
      </div2 -->

    </div1>
    <issue id="many-to-many-as-repeated-properties">
      The direct graph is arguably more faithful to the conceptual model if it reflects e.g. a person with multiple addresses (some many-to-many Person2Address table) as repeated properties.
      It is difficult to detect which tables with exactly two foreign keys and no other attributes are many-to-many.
      As a <a href="http://www.w3.org/mid/20101102085620.GA7095@w3.org">counter example</a>, a Wedding table may have exactly two spouses but it's still not a many-to-many relation in most places.
    </issue>
    <div1 id="notation">
      <head>Notation for this Document</head>

      <div2 id="types">
	<head>Notation for Types</head>
	<p><term>A </term> <termdef id="T_type">a type</termdef></p>
	<p><term>A? </term> <termdef id="T_opt">an optional argument of type A</termdef></p>
	<p><term>A ⊔ B </term> <termdef id="T_disjoint_union">disjoint union of A and B</termdef></p>
	<p><term>( A, B ) </term> <termdef id="T_tuple">tuple (Cartesian product) of types A and B</termdef></p>
	<p><term>[ A ] </term> <termdef id="T_list">list of elements of type A</termdef></p>
	<p><term>{ A } </term> <termdef id="T_set">set of elements of type A</termdef></p>
	<p><term>{ A→B } </term> <termdef id="T_map">finite map of elements of type A to elements of type B</termdef></p>
      </div2>
      <div2 id="injectors">
	<head>Notation for Injectors</head>
	<p><term>a </term> <termdef id="inj_instance">an instance of an A</termdef></p>
	<p><term>( a1, b1 ) </term> <termdef id="inj_tuple">a tuple with elements a1 and b1</termdef></p>
	<p><term>[ a1, a2 ] </term> <termdef id="inj_list">list with elements a1 and a2</termdef></p>
	<p><term>{ a1, a2 } </term> <termdef id="inj_set">set with elements a1 and a2</termdef></p>
	<p><term>{ a1→b1, a2→b2 } </term> <termdef id="inj_map">map with elements with key a1 mapped to b1 and key a2 mapped to b2</termdef></p>
      </div2>
      <div2 id="accessors">
	<head>Accessor Functions</head>
	<p><term>AB[a] </term> <termdef id="map_get">in a map of A to B, the instance of B for a given A</termdef></p>
      </div2>
    </div1>
    <div1 id="models">
      <head>Data Model Definition (Normative)</head>

      <div class="syntaxmenu">
	<p>The buttons below can be used to show or hide the available syntaxes.</p>
	<form action="">
	  <p>
	    <input id="hide-fs" onclick="display('setnotation','none');      set_display_by_id('hide-fs', 'none'); set_display_by_id('show-fs', '');" value="Hide Set-Style Syntax" type="button"/>
	    <input id="show-fs" onclick="display('setnotation','table-row');      set_display_by_id('hide-fs', '');       set_display_by_id('show-fs', 'none');" style="display: none;" value="Show Set-Style Syntax" type="button"/>
	    <input style="display: none;" id="hide-rs" onclick="display('english', 'none');      set_display_by_id('hide-rs', 'none');       set_display_by_id('show-rs', '');" value="Hide English Syntax" type="button"/>
	    <input id="show-rs" onclick="display('english', 'table-row');      set_display_by_id('hide-rs', '');       set_display_by_id('show-rs', 'none');" style="" value="Show English Syntax" type="button"/>
	    <!-- input style="display: none;" id="hide-ts" onclick="display('prolog', 'none');      set_display_by_id('hide-ts', 'none');       set_display_by_id('show-ts', '');" value="Hide Prolog Syntax" type="button"/>
	    <input id="show-ts" onclick="display('prolog', 'table-row');      set_display_by_id('hide-ts', '');       set_display_by_id('show-ts', 'none');" style="" value="Show Prolog Syntax" type="button"/>
	    <input style="display: none;" id="hide-ms" onclick="display('ml', 'none');            set_display_by_id('hide-ms', 'none');             set_display_by_id('show-ms', '');" value="Hide Ml Syntax" type="button"/>
	    <input id="show-ms" onclick="display('ml','table-row');      set_display_by_id('hide-ms', '');       set_display_by_id('show-ms', 'none');" style="" value="Show Ml Syntax" type="button"/ -->
	    <input style="display: none;" id="hide-xs" onclick="display('scala', 'none');      set_display_by_id('hide-xs', 'none');       set_display_by_id('show-xs', '');" value="Hide Scala Syntax" type="button"/>
	    <input id="show-xs" onclick="display('scala', 'table-row');      set_display_by_id('hide-xs', '');       set_display_by_id('show-xs', 'none');" style="" value="Show Scala Syntax" type="button"/>
	  </p>
	</form>
      </div>

      <div2 id="Rel">
	<head>Reference Database Model Definition (Normative)</head>
	<p>
There are many models for databases in SQL literature; because the Direct Mapping does not rely on column position, we use a model which assumes a 1:1 correspondance between attribute (column name) and value, i.e. a map.
Starting with a traditional model of a relational database we define a Relation (a table) which has a name, a Header, Body and primary/foreign key details.
The Body contains maps from attribute names to values and the Header provides the datatypes to interpret those values.
	</p><!-- \M-x replace-regexp num="[0-9]+" num="\#" (replace-regexp "num=\"[0-9]+\"" "num=\"#\"")  num="0" -->
	<scrap lang="ebnf">
	  <head>Relational Definition</head>
	  <prod id="Rel-Database" num="1">
	    <lhs>Database</lhs>
	    <rhs>{ <nt def="Rel-Table">TableName</nt> → <nt def="Rel-Table">Table</nt> }</rhs>
	    <english>A <dfn>relational database</dfn> is a mapping of relation name to relation.</english>
	    <scala>  case class Database( m:Map[TableName, Table] )</scala>
	  </prod>
	  <prod id="Rel-Table" num="2">
	    <lhs>Table</lhs>
	    <rhs>( <nt def="Rel-Header">Header</nt>, [<nt def="Rel-CandidateKey">CandidateKey</nt>], <nt def="Rel-CandidateKey">CandidateKey</nt>?, <nt def="Rel-ForeignKeys">ForeignKeys</nt>, <nt def="Rel-Body">Body</nt> ) where the 2nd slot is a list of candidate keys that apply to the table, and the 3rd is an optional candidate key use as the primary key</rhs>
	    <english>A <dfn>relation</dfn> has a header, a list of candidate keys, a primary key (of type candidate key), a mapping of foreign keys, and a body.</english>
	    <scala>  case class Table (header:Header, body:Body, candidates:List[CandidateKey], pk:Option[CandidateKey], fks:ForeignKeys)</scala>
	  </prod>
	  <prod id="Rel-Header" num="3">
	    <lhs>Header</lhs>
	    <rhs>{ <nt def="Rel-AttrName">AttrName</nt> → <nt def="Rel-SQLDatatype">SQLDatatype</nt> }</rhs>
	    <english>A <dfn>header</dfn> is a mapping from attribute name to SQL datatype.</english>
	    <scala>  case class Header (types:Map[AttrName, SQLDatatype])</scala>
	  </prod>
	  <prod id="Rel-CandidateKey" num="4">
	    <lhs>CandidateKey</lhs>
	    <rhs>[ <nt def="Rel-AttrName">AttrName</nt> ]</rhs>
	    <english>A <dfn>candidate key</dfn> is a list of attribute names.</english>
	    <scala>  type CandidateKey = List[AttrName]</scala>
	  </prod>
	  <prod id="Rel-ForeignKeys" num="5">
	    <lhs>ForeignKeys</lhs>
	    <rhs>{ [<nt def="Rel-AttrName">AttrName</nt>] → ( <nt def="Rel-Table">Table</nt>, [<nt def="Rel-AttrName">AttrName</nt>] ) }</rhs>
	    <english><dfn>Foreign keys</dfn> is a mapping from a list of attribute names to a relation and a list of attribute names.</english>
	    <scala>  type ForeignKeys = Map[AttrName, Target]
  case class Target (rel:TableName, attrs:CandidateKey)</scala>
	  </prod>
	  <prod id="Rel-SQLDatatype" num="6">
	    <lhs>SQLDatatype</lhs>
	    <rhs>{ INT | FLOAT | DATE | TIME | TIMESTAMP | CHAR | VARCHAR | STRING }</rhs>
	    <english>An <dfn>SQL datatype</dfn> is an INT, FLOAT, DATE, TIME, TIMESTAMP, CHAR, VARCHAR or STRING as defined in the SQL specification <bibref ref="SQLFN"/>.</english>
	    <scala>  sealed abstract class SQLDatatype
  case class SQLInt () extends SQLDatatype
  case class SQLFloat () extends SQLDatatype
  …
  case class SQLString () extends SQLDatatype
</scala>
	  </prod>
	  <prod id="Rel-Body" num="7">
	    <lhs>Body</lhs>
	    <rhs>[ <nt def="Rel-Tuple">Tuple</nt> ]</rhs>
	    <english>A <dfn>body</dfn> is a list of (potentially duplicate) tuples.</english>
	    <scala>  type Body = List[Tuple]</scala>
	  </prod>
	  <prod id="Rel-Tuple" num="8">
	    <lhs>Tuple</lhs>
	    <rhs>{ <nt def="Rel-AttrName">AttrName</nt> → <nt def="Rel-CellValue">CellValue</nt> }</rhs>
	    <english>A <dfn>tuple</dfn> is a mapping from attribute name to cell value.</english>
	    <scala>  case class Tuple (m:Map[AttrName, CellValue])</scala>
	  </prod>
	  <prod id="Rel-CellValue" num="9">
	    <lhs>CellValue</lhs>
	    <rhs>value | Null</rhs>
	    <english>A <dfn>cell value</dfn> is a scalar value in some SQL datatype, or SQL NULL.</english>
	    <scala>  abstract class CellValue
  case class LexicalValue (s:String) extends CellValue
  case class ␀ () extends CellValue</scala>
	  </prod>
	</scrap>
      </div2>
      <div2 id="RDFdef">
	<head>RDF Model Definition (Non-normative)</head>
	<p>
	  Per <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#section-rdf-graph">RDF Concepts and Abstract Syntax</a>, an RDF graph is a set of triples of a subject, predicate and object.
	  The subject may be an IRI or a blank node, the predicate must be an IRI and the object may be an IRI, blank node, or an RDF literal.
	</p>
	<p>
	  This section recapitulates for convience the formal definition of RDF.
	</p>
	<scrap lang="ebnf">
	  <head>RDF Definition</head>
	  <prod id="RDF-Graph" num="10">
	    <lhs>Graph</lhs>
	    <rhs>{ <nt def="RDF-Triple">Triple</nt> }</rhs>
	    <english>An <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-rdf-graph">RDF graph</a></dfn> is a set of RDF triples.</english>
	    <scala>  type RDFGraph = Set[Triple]</scala>
	  </prod>
	  <prod id="RDF-Triple" num="11">
	    <lhs>Triple</lhs>
	    <rhs>( Subject, Predicate, Object )</rhs>
	    <english>An <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-rdf-triple">RDF triple</a></dfn> contains a subject, predicate and object.</english>
	    <scala>  case class Triple (s:Subject, p:IRI, o:Object)</scala>
	  </prod>
	  <prod id="RDF-Subject" num="12">
	    <lhs>Subject</lhs>
	    <rhs><nt def="RDF-IRI">IRI</nt> | <nt def="RDF-BlankNode">BlankNode</nt></rhs>
	    <english>A <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-subject">subject</a></dfn> is an IRI or a blank node.</english>
	    <scala>  sealed abstract class Node <span class="comment">// factor out IRIs and BNodes</span>
  case class NodeIRI(i:IRI) extends Node
  case class NodeBNode(b:BNode) extends Node

  sealed abstract class Subject
  case class SubjectNode(n:Node) extends Subject
</scala>
	  </prod>
	  <prod id="RDF-Predicate" num="13">
	    <lhs>Predicate</lhs>
	    <rhs><nt def="RDF-IRI">IRI</nt></rhs>
	    <english>A <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-predicate">predicate</a></dfn> is an IRI.</english>
	    <scala>  sealed abstract class Predicate
  case class PredicateIRI(i:IRI) extends Predicate</scala>
	  </prod>
	  <prod id="RDF-Object" num="14">
	    <lhs>Object</lhs>
	    <rhs><nt def="RDF-IRI">IRI</nt> | <nt def="RDF-BlankNode">BlankNode</nt> | <nt def="RDF-Literal">Literal</nt></rhs>
	    <english>An <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-object">object</a></dfn> is an IRI, a blank node, or a literal.</english>
	    <scala>  sealed abstract class Object
  case class ObjectNode(n:Node) extends Object
  case class ObjectLiteral (n:Literal) extends Object</scala>
	  </prod>
	  <prod id="RDF-IRI" num="15">
	    <lhs>IRI</lhs>
	    <rhs><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-URI-reference">RDF URI-reference</a> as subsequently <a href="http://www.w3.org/TR/rdf-sparql-query/#docTerminology">restricted by SPARQL</a></rhs>
	    <english>An <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-rdf-">IRI</a></dfn> is an <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-URI-reference">RDF URI reference</a> as subsequently <a href="http://www.w3.org/TR/rdf-sparql-query/#docTerminology">restricted by SPARQL</a>.</english>
	    <scala>  case class IRI(iri:String)</scala>
	  </prod>
	  <prod id="RDF-BlankNode" num="16">
	    <lhs>BlankNode</lhs>
	    <rhs><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-blank-node">RDF blank node</a></rhs>
	    <english>A <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-blank-node">blank node</a></dfn> is an arbitrary term used only to establish graph connectivity.</english>
	    <scala>  case class BNode(label:String)</scala>
	  </prod>
	  <prod id="RDF-Literal" num="17">
	    <lhs>Literal</lhs>
	    <rhs><nt def="RDF-PlainLiteral">PlainLiteral</nt> | <nt def="RDF-TypedLiteral">TypedLiteral</nt></rhs>
	    <english>A <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-literal">literal</a></dfn> is either a plain literal or a typed literal.</english>
	    <scala>  sealed abstract class Literal
  case class LiteralTyped(i:TypedLiteral) extends Literal
  case class LiteralPlain(b:PlainLiteral) extends Literal</scala>
	  </prod>
	  <prod id="RDF-PlainLiteral" num="18">
	    <lhs>PlainLiteral</lhs>
	    <rhs>(lexicalForm) | (lexicalForm, langageTag).</rhs>
	    <english>A <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-plain-literal">plain literal</a></dfn> has a <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-lexical-form">lexical form</a> and an optional <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-language-identifier">language tag</a>.</english>
	    <scala>  case class PlainLiteral(value:String, langtag:Option[String])</scala>
	  </prod>
	  <prod id="RDF-TypedLiteral" num="19">
	    <lhs>TypedLiteral</lhs>
	    <rhs>(lexicalForm, IRI).</rhs>
	    <english>An <dfn><a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-typed-literal">typed literal</a></dfn> has a <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-lexical-form">lexical form</a> and a <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-datatype-URI">datatype IRI</a>.</english>
	    <scala>  case class TypedLiteral(value:String, datatype:IRI)</scala>
	  </prod>
	</scrap>
      </div2>
    </div1>

    <div1 id="alg">
      <head>Direct Mapping Definition (Normative)</head>
      <p>
The direct mapping is a formula for creating an RDF graph from the tuples in a relation.
A <emph id="base">base</emph> IRI defines a web space for the labels in this graph; all labels are generated by appending to the base.
The functions <code>scalar</code> and <code>reference</code> extract the non-Null scalar and reference attributes respectively.
      </p>

      <scrap>
	  <prod id="direct-references" num="20">
	    <lhs>references(T, R)</lhs>
	    <rhs>{ K ∣ ∄(T(A) = Null ∣ A ∈ K) ∧ K ≠ R.<nt def="Rel-PrimaryKey">PrimaryKey</nt> ∣ K ∈ R.<nt def="Rel-ForeignKeys">ForeignKeys</nt> }</rhs>
	    <english>The <dfn>references</dfn> function returns the attributes in any of a relation's foreign keys.</english>
	    <scala>  def references (t:Tuple, r:Table):Set[List[AttrName]] = {
    val allFKs:Set[List[AttrName]] = r.fks.keySet
    val nulllist:Set[AttrName] = t.nullAttributes(r.header)
    val nullFKs:Set[List[AttrName]] = allFKs.flatMap(a =&gt; {
      val int:Set[AttrName] = nulllist &amp; a.toSet
      if (int.toList.length == 0) None else List(a)
    })

    /** Check to see if r's primary key is a hierarchical key.
     * http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
    if (r.pk.isDefined &amp;&amp; r.fks.contains(r.pk.get))
      r.fks.keySet -- nullFKs - r.fks(r.pk.get).attrs
    else
      r.fks.keySet -- nullFKs
  }</scala>
	  </prod>
	  <prod id="direct-scalars" num="21">
	    <lhs>scalars(T)</lhs>
	    <rhs>{ A in T ∣ A ≠ Null ∧ [A] ∉ <nt def="direct-references">references</nt>(T) }</rhs>
	    <english>The <dfn>scalars</dfn> function returns the attributes which are NOT in any of a relation's foreign keys.</english>
	    <scala>  def scalars (t:Tuple, r:Table):Set[AttrName] = {
    val allAttrs:Set[AttrName] = r.header.keySet
    val nulllist:Set[AttrName] = t.nullAttributes(r.header)
    val refs = references(t, r) filter (a => a.length == 1) map (a => a(0))
    allAttrs -- refs -- nulllist
  }</scala>
	  </prod>
      </scrap>

      <p>
	Each tuple in a relation with some candidate key can be uniquely identified by values of that key.
	A <a href="#direct-KeyMap">KeyMap</a>(R) maps the candidate keys in a relation to a map of key values to the subject nodes assigned to each tuple.
      </p>

      <scrap>
	  <prod id="direct-KeyMap" num="22">
	    <lhs>KeyMap</lhs>
	    <rhs>{ <nt def="directR">CandidateKey</nt> → { [<nt def="directR">CellValue</nt>] → <nt def="Subject">RDF Node</nt> } }</rhs>
	    <english>A <dfn>KeyMap</dfn> is a map from candidate key to a map from list of cell values to RDF nodes.</english>
	    <scala>  type KeyMap = Map[CandidateKey, Map[List[CellValue], Node]]</scala>
	  </prod>
	  <prod id="direct-RowIRI" num="23">
	    <lhs>RowIRI</lhs>
	    <rhs>{ <nt def="directR">CandidateKey</nt> → <nt def="KeyMap">KeyMap</nt> }</rhs>
	    <english>A <dfn>RowIRI</dfn> is a map from relation name to key map.</english>
	    <scala>  type RowIRI = Map[TableName, KeyMap]</scala>
	  </prod>
      </scrap>

      <p>
	The function <a href="#direct-directDB">directDB</a>(DB) computes a RowIRI M for each relation with one or more candidate keys.
	The function <a href="#direct-directR">directR</a>(R, M) maps the Tuples in a Table R to an RDF graph.
	The following definitions assume the existance of some BaseIRI U and Database DB.
      </p>

      <scrap>
	  <prod id="direct-directDB" num="24">
	    <lhs>directDB()</lhs>
	    <rhs>{ <nt def="directR">directR</nt>(R, M) ∣ R ∈ DB }</rhs>
	    <english>The <dfn>directDB</dfn> of a database DB is a set of RDF triples (<a href="#RDF-Graph">RDF graph</a>) created by calling directR on each relation in DB.</english>
	    <scala>  def directDB (u:BaseIRI, db:Database) : RDFGraph = {
    val idxables = db.keySet filter { rn =&gt; !db(rn).candidates.isEmpty }
    val rowIRI = idxables map {rn =&gt; rn -&gt; relation2KeyMap(u, db(rn))}
    db.keySet.flatMap(rn =&gt; directR(u, db(rn), rowIRI, db))
  }</scala>
	  </prod>
	  <prod id="direct-directR" num="25">
	    <lhs>directR(R, M)</lhs>
	    <rhs>{ <nt def="directT">directT</nt>(T, R, M) ∣ T ∈ R.Body }</rhs>
	    <english>The <dfn>directR</dfn> of a relation is a set of RDF triples created by calling directT on each tuple in the body of the database.</english>
	    <scala>  def directR (u:BaseIRI, r:Table, nodes:RowIRI, db:Database) : RDFGraph =
    body(r).flatMap(t => directT(u, t, r, nodes, db))</scala>
	  </prod>
	  <prod id="direct-directT" num="26">
	    <lhs>directT(T, R, M)</lhs>
	    <rhs>{ <nt def="directS">directS</nt>(S, T, R, M) ∣ S = subject(T, R, M) }</rhs>
	    <english>The <dfn>directT</dfn> of a tuple in a relation is a set of RDF triples created by calling directS with an S created by the function <code>subject</code>.</english>
	    <scala>  def directT (u:BaseIRI, t:Tuple, r:Table, nodes:RowIRI, db:Database) : Set[Triple] = {
    val s = subject(t, r, nodes, db)
    directS(u, s, t, r, nodes, db)
  }</scala>
	  </prod>
	  <prod id="direct-subject" num="27">
	    <lhs>subject(T, R, M)</lhs>
	    <rhs><code>if</code> (pk(R) = ∅) <code>then</code> new blank node <code>else</code> <nt def="subject">rowIRI</nt>(R, T[pk(R)]) # references the ultimate referent of hierarchical key</rhs>
	    <english>The <dfn>subject</dfn> identifier for a tuple in a relation is fresh blank node, if there is no primary key, or the IRI returned from rowIRI of that primary key's attribute values in that tuple.</english>
	    <scala>  def subject (t:Tuple, r:Table, nodes:RowIRI, db:Database):Node =
    if (r.candidates.size &gt; 0) {
      // Known to have at least one key, so take the first one.
      val k = r.candidates(0)
      val vs = t.lexvaluesNoNulls(k)
      nodes.ultimateReferent(r.name, k, vs, db)
    } else
      /** Table has no candidate keys. */
      freshbnode()</scala>
	  </prod>
	  <prod id="direct-directS" num="28">
	    <lhs>directS(S, T, R, M)</lhs>
	    <rhs>{ <nt def="directL">directL</nt>(S, R, A) ∣ A ∈ scalars(T, R) } ∪ { <nt def="directL">directN</nt>(S, As, T, M) ∣ As ∈ references(T, R) }<!-- ∪ { directP(R, S) } --></rhs>
	    <english>The <dfn>directS</dfn> of a subect, tuple and relation is the set of RDF triples created by:
	    <ul>
	      <li>calling directL on each scalar attribute in T,</li>
	      <li>calling directN on each foreign key in T</li>
	    </ul>
	    </english>
	    <scala>  def directS (u:BaseIRI, s:Node, t:Tuple, r:Table, nodes:RowIRI, db:Database) : Set[Triple] = {
    references(t, r).map(as =&gt; directN(u, s, as, r, t, nodes)) ++
    scalars(t, r).map(a =&gt; directL(u, r.name, s, a, r.header, t))
  }</scala>
	  </prod>
	  <prod id="direct-directL" num="29">
	    <lhs>directL(S, R, A)</lhs>
	    <rhs><nt def="RDF-triple">triple</nt>(S, <nt def="base-propertyIRI">propertyIRI</nt>(R, [A]), <nt def="base-literalmap">literalmap</nt>(A))</rhs>
	    <english>The <dfn>directL</dfn> of a subject, relation and attribute is the RDF triple with that subject, the predicate returned from propertyIRI, and the object returned from literalmap.</english>
	    <scala>  def directL (u:BaseIRI, rn:TableName, s:Node, a:AttrName, h:Header, t:Tuple) : Triple = {
    val p = propertyIRI (u, rn, List(a))
    val l = t.lexvalue(a).get
    val o = literalmap(l, h.sqlDatatype(a))
    Triple(s, p, o)
  }</scala>
	  </prod>
	  <prod id="direct-directN" num="30">
	    <lhs>directN(S, R, As)</lhs>
	    <rhs><nt def="RDF-triple">triple</nt>(S, <nt def="base-propertyIRI">propertyIRI</nt>(R, As), <nt def="base-rowIRI">rowIRI</nt>(R, As))</rhs>
	    <english>The <dfn>directN</dfn> of a subject, relation and list of attributes is the RDF triple with that subject, a predicate returned from propertyIRI, and the object returned by rowIRI of the list of attributes.</english>
	    <scala>  def directN (u:BaseIRI, s:Node, as:List[AttrName], r:Table, t:Tuple, nodes:RowIRI) : Triple = {
    val p = propertyIRI (u, r.name, as)
    val ls:List[LexicalValue] = t.lexvaluesNoNulls(as)
    val target = r.fks(as)
    val o:Object = nodes(target.rel)(target.attrs)(ls)
    Triple(s, p, o)
  }</scala>
	  </prod>
	  <!-- prod num="42">
	    <lhs>directP(R, S)</lhs>
	    <rhs><nt def="RDF-triple">triple</nt>(S, rdf:type, <a href="#base-typeIRI">typeIRI</a>(R))</rhs>
	    <english></english>
	  </prod -->
      </scrap>

      <p>
	<a href="#base-rowIRI">rowIRI</a> generates a <a href="#rowIRI">row IRI</a>.
	<a href="#base-propertyIRI">propertyIRI</a> generates a <a href="#propertyIRI">property IRI</a>.
<!-- 	In the interest of keeping the generated RDF graph <a href="http://www.jenitennison.com/blog/node/136">linked-data-friendly</a> and in deference to the resolution of <a href="http://www.w3.org/2001/tag/issues.html#httpRange-14">W3C Tag issue httpRange-14</a>, the generated node and predicate labels can come in two flavors, hash or slash.
-->
      </p>
      <scrap>
	<prod id="base-rowIRI" num="31">
	  <lhs>rowIRI(R, As)</lhs>
	  <rhs><nt def="RDF-IRI">IRI</nt>(<nt def="base">base</nt> + "/" + UE(R.name) + "/" + (join(',', UE(A.name) + "=" + UE(A.value)) ∣ A ∈ As ))</rhs>
	  <english>A <dfn>rowIRI</dfn> is a concatonation, with punctuation as separators, of a base IRI, url-encoded relation name, and the attribute name/value pairs in the list of attributes.</english>
	  <scala>  def rowIRI (u:BaseIRI, rn:TableName, as:List[AttrName], ls:List[LexicalValue]) : IRI = {
    val pairs:List[String] = as.zip(ls).map(x =&gt; UE(x._1) + "=" + UE(x._2.s))
    u + ("/" + UE(rn) + "/" + pairs.mkString("_"))
  }</scala>
	  <tip><a class="tooltip">RDF Graph (set of triples)</a></tip>
	</prod>
	<prod id="base-propertyIRI" num="32">
	  <lhs>propertyIRI(R, As)</lhs>
	  <rhs><nt def="RDF-IRI">IRI</nt>(<nt def="base">base</nt> + "/" + (join(',', UE(A.name)) ∣ A ∈ As ) "#" As.name)</rhs>
	  <english>A <dfn>propertyIRI</dfn> is a concatonation, with punctuation as separators, of a base IRI, url-encoded relation name, and the attribute names the list of attributes.</english>
	  <scala>  def propertyIRI (u:BaseIRI, rn:TableName, as:List[AttrName]) : IRI =
    u + ("/" + UE(rn) + "#" + as.mkString("_"))</scala>
	</prod>
	<!-- prod id="base-typeIRI" num="43">
	  <lhs>typeIRI(R)</lhs>
	  <rhs><nt def="RDF-IRI">IRI</nt>(<nt def="base">base</nt> + "#" + R.name)</rhs>
	  <english></english>
	</prod -->
	<!-- 
	<prod id="base-rowIRI" num="33">
	  <lhs>rowIRI(R, A)</lhs>
	  <rhs><nt def="hash-rowIRI">hash-rowIRI</nt>(R, A) | <nt def="slash-rowIRI">slash-rowIRI</nt>(R, A)</rhs>
	</prod>
	<prod id="base-propertyIRI" num="34">
	  <lhs>propertyIRI(R, A)</lhs>
	  <rhs><nt def="hash-propertyIRI">hash-propertyIRI</nt>(R, A) | <nt def="slash-propertyIRI">slash-propertyIRI</nt>(R, A)</rhs>
	</prod>
	<prod id="hash-rowIRI" num="35">
	  <lhs>hash-rowIRI(R, A)</lhs>
	  <rhs><nt def="RDF-IRI">IRI</nt>(<nt def="base">base</nt> + "/" + R.name "/" A.name + "." + A.value + "")</rhs>
	</prod>
	<prod id="hash-propertyIRI" num="36">
	  <lhs>hash-propertyIRI(R, A)</lhs>
	  <rhs><nt def="RDF-IRI">IRI</nt>(<nt def="base">base</nt> + "/" + R.name "#" A.name)</rhs>
	</prod>
	<prod id="slash-rowIRI" num="37">
	  <lhs>slash-rowIRI(R, A)</lhs>
	  <rhs><nt def="RDF-IRI">IRI</nt>(<nt def="base">base</nt> + "/" + R.name "/" A.name + "." + A.value)</rhs>
	</prod>
	<prod id="slash-propertyIRI" num="38">
	  <lhs>slash-propertyIRI(R, A)</lhs>
	  <rhs><nt def="RDF-IRI">IRI</nt>(<nt def="base">base</nt> + "/" + R.name "/" A.name)</rhs>
	</prod>
	-->
      </scrap>

      <p>
	<code>literalmap</code> produces RDF literal with XSD datatypes with this type mapping TM:
      </p>
      <scrap>
	<prod id="base-literalmap" num="39">
	  <lhs>literalmap(A)</lhs>
	  <rhs><nt def="RDF-Literal">Literal</nt>(A[V], SQL2XSD[A]) ∣ SQL2XSD is the mapping from SQL datatypes to XML datatypes below:</rhs>
	</prod>
      </scrap>
      <table id="XMLdt" cellpadding="2" cellspacing="0" border="1">
	<caption>XML Datatypes for SQL Datatypes</caption>
	<thead>
	  <tr><th>SQL		</th><th>XSD data type for typed literals, "plain literal" for <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-plain-literal">plain literals</a></th></tr>
	</thead>
	<tbody>
	  <tr><td>INT		</td><td>http://www.w3.org/TR/xmlschema-2/#integer </td></tr>
	  <tr><td>FLOAT		</td><td>http://www.w3.org/TR/xmlschema-2/#float   </td></tr>
	  <tr><td>DATE		</td><td>http://www.w3.org/TR/xmlschema-2/#date	   </td></tr>
	  <tr><td>TIME		</td><td>http://www.w3.org/TR/xmlschema-2/#time	   </td></tr>
	  <tr><td>TIMESTAMP	</td><td>http://www.w3.org/TR/xmlschema-2/#dateTime</td></tr>
	  <tr><td>CHAR		</td><td>plain literal                             </td></tr>
	  <tr><td>VARCHAR	</td><td>plain literal                             </td></tr>
	  <tr><td>STRING	</td><td>plain literal                             </td></tr>
	</tbody>
      </table>

      <p>
	<code>UE</code> (url-encode) is the conventional url encoding used for e.g. HTML CGI forms:
      </p>
      <scrap>
	<prod id="base-UE" num="40">
	  <lhs>UE(T)</lhs>
	  <rhs>url-encode T per <a href="http://www.w3.org/TR/wsdl#_http:urlEncoded">WSDL urlEncoded</a>.</rhs>
	</prod>
      </scrap>

    </div1>

    <!-- div1 id="extend">
      <head>Extending the Direct Mapping</head>
      <p>
	The direct mapping is extensible, producing more triples in the direct graph.
	Below are some useful extensions.
      </p>
      <div2 id="WithType">
	<head>Type Annotations (Normative)</head>
	<p>
	  In some circumstances, it is useful to extend the direct mapping to include triples for the primary key attributes.
	  This supplements the <a href="#emp-addr">Employees/Addresses example</a> with the following triples:
	</p>
	<turtle>
@base &lt;http://foo.example/DB/&gt;
@prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .

&lt;http://foo.example/DB/People/ID=7&gt; a &lt;http://foo.example/DB/#People&gt; .
&lt;http://foo.example/DB/People/ID=8&gt; a &lt;http://foo.example/DB/#People&gt; .
&lt;http://foo.example/DB/Addresses/ID=18&gt; a &lt;http://foo.example/DB/#Addresses&gt; .
	</turtle>
	<p>
	  This graph is defined by adding a <code>directP(R, S)</code> function which asserts a triple with a predicate <code>rdf:type</code>:
	</p>
	<scrap>
	  <prod num="41">
	    <lhs>directT(R, T)</lhs>
	    <rhs>{ directL(R, S, A) ∣ A ∈ scalar(T) } ∪ { directN(R, S, A) ∣ A ∈ reference(T) }  ∪ { directP(R, S) } ∣ S = rowIRI(R, T[pk(R)])</rhs>
	    <english></english>
	  </prod>
	  <prod num="42">
	    <lhs>directP(R, S)</lhs>
	    <rhs>triple(S, rdf:type, typeIRI(R))</rhs>
	    <english></english>
	  </prod>
	  <prod num="43">
	    <lhs>typeIRI(R)</lhs>
	    <rhs>IRI(base + "#" + R.name)</rhs>
	    <english></english>
	  </prod>
	</scrap>
      </div2>
      <div2 id="ManyToMany">
	<head>Many to Many Mappings (Normative)</head>
	<table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	  <caption>People</caption>
	  <tbody>
	    <tr>
	      <th class="pk">PK</th>
	      <th colspan="1"></th>
	    </tr>
	    <tr>
	      <th class="pk">ID</th>
	      <th>fname</th>
	    </tr>
	    <tr>
	      <td class="pk" id="person7b">7</td>
	      <td>Bob</td>
	    </tr>
	    <tr>
	      <td class="pk">8</td>
	      <td>Sue</td>
	    </tr>
	  </tbody>
	</table>
	<table class="nonRight" cellpadding="2" cellspacing="0" border="1">
	  <caption>Addresses</caption>
	  <tbody>
	    <tr>
	      <th class="pk">PK</th>
	      <th colspan="2"></th>
	    </tr>
	    <tr>
	      <th class="pk">ID</th>
	      <th>City</th>
	      <th>State</th>
	    </tr>
	    <tr>
	      <td class="pk" id="addr18c">18</td>
	      <td>Cambridge</td>
	      <td>MA</td>
	    </tr>
	    <tr>
	      <td class="pk" id="addr19b">19</td>
	      <td>Cambridge</td>
	      <td>UK (yeah, not a state...)</td>
	    </tr>
	  </tbody>
	</table>
	<table class="right" cellpadding="2" cellspacing="0" border="1">
	  <caption>Per2Addr</caption>
	  <tbody>
	    <tr>
	      <th class="pk">PK</th>
	      <th colspan="1"></th>
	    </tr>
	    <tr>
	      <th class="pk">person</th>
	      <th>addr</th>
	    </tr>
	    <tr>
	      <td class="pk"><a href="#person7b">7</a></td>
	      <td><a href="#addr18b">18</a></td>
	    </tr>
	    <tr>
	      <td class="pk"><a href="#person7b">7</a></td>
	      <td><a href="#addr19b">19</a></td>
	    </tr>
	  </tbody>
	</table>
	<p>
	  In some circumstances, it is useful to extend the direct mapping to include triples for the primary key attributes.
	  This supplements the <a href="#emp-addr">Employees/Addresses example</a> with the following triples:
	</p>
	<turtle>
@base &lt;http://foo.example/DB/&gt;
@prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .

&lt;People/ID=7&gt; &lt;People#ID&gt; 7 .
&lt;People/ID=7&gt; &lt;People#fname&gt; "Bob" .
&lt;People/ID=7&gt; &lt;People#addr&gt; &lt;Addresses/ID=18&gt; .
&lt;People/ID=7&gt; &lt;People#addr&gt; &lt;Addresses/ID.19&gt; .
&lt;People/ID=8&gt; &lt;People#ID&gt; 8 .&lt;People/ID=8&gt; &lt;People#fname&gt; "Sue" .

&lt;Addresses/ID=18&gt; &lt;Addresses#ID&gt; 18 .
&lt;Addresses/ID=18&gt; &lt;Addresses#city&gt; "Cambridge" .
&lt;Addresses/ID=18&gt; &lt;Addresses#state&gt; "MA" .
&lt;Addresses/ID.19&gt; &lt;Addresses#ID&gt; 19 .&lt;Addresses/ID.19&gt; &lt;Addresses#city&gt; "Cambridge" .
&lt;Addresses/ID.19&gt; &lt;Addresses#state&gt; "UK" .
	</turtle>
	<p>
	  The Many to Many graph is defined by overloading <code>directR</code>.
	  This definition follows the <code>direct mapping</code> for all relations which are not many-to-many, and defines a single triple in each many-to-many relation.
	</p>
	<scrap>
	  <prod id="manytomany-directR" num="44">
	    <lhs>manytomany(R)</lhs>
	    <rhs>{ R ∣ R has exactly two attributes (X, Y), being foreign keys to RX.PKX and RY.PKY respectively }</rhs>
	    <english></english>
	  </prod>
	  <prod id="many2many-directDB" num="45">
	    <lhs>directDB(db)</lhs>
	    <rhs>{ <nt def="directR">directR</nt>(r) ∣ r ∉ manytomany(db.R) } ∪ { <nt def="directR">repeatpropertyR</nt>(r) ∣ r ∈ manytomany(db.R) }</rhs>
	    <english></english>
	  </prod>
	  <prod id="manytomany-repeatpropertyR" num="46">
	    <lhs>repeatpropertyR(R)</lhs>
	    <rhs>{ <nt def="repeatpropertyT">repeatpropertyT</nt>(R, T) ∣ T ∈ R.Body }</rhs>
	    <english></english>
	  </prod>
	  <prod id="many2many-repeatpropertyT" num="47">
	    <lhs>repeatpropertyT(R, T)</lhs>
	    <rhs><nt def="RDF-triple">triple</nt>(<nt def="base-rowIRI">rowIRI</nt>(RX, PKX), <nt def="base-propertyIRI">propertyIRI</nt>(R, Y), <nt def="base-rowIRI">rowIRI</nt>(RY, PKY))</rhs>
	    <english></english>
	  </prod>
	</scrap>

      </div2>
    </div1 -->

    <div1 id="refs">
      <head>References</head>
    </div1>
  </body>
  <back>
    <blist>
      <bibl id="SPARQL" href="http://www.w3.org/TR/rdf-sparql-query/">SPARQL Query Language for RDF, Eric Prud'hommeaux and Andy Seaborne 2008.</bibl>
      <bibl id="SQLFW">SQL. ISO/IEC 9075-1:2008 SQL – Part 1: Framework (SQL/Framework) International Organization for Standardization, 27 January 2009.</bibl>
      <bibl id="SQLFN">ISO/IEC 9075-2:2008 SQL – Part 2: Foundation (SQL/Foundation)
International Organization for Standardization, 27 January 2009.</bibl>
      <bibl id="RDF" href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/">Resource Description Framework (RDF): Concepts and Abstract Syntax, G. Klyne, J. J. Carroll,  Editors, W3C Recommendation, 10 February 2004</bibl>
      <bibl id="ReuseableIDs" href="http://esw.w3.org/topic/Rdb2RdfXG/ReusableIdentifier">Reusable Identifiers in the RDB2RDF mapping language, Michael Hausenblas and Themis Palpanas, 2009.</bibl>
      <bibl id="URI" href="http://tools.ietf.org/html/rfc3986">RFC3986 - Uniform Resource Identifier (URI): Generic Syntax</bibl>
      <bibl id="IRI" href="http://tools.ietf.org/html/rfc3987">RFC3987 - Internationalized Resource Identifier (IRIs)</bibl>
    </blist>
    <div1 id="sec-cvsLog">
      <head>CVS History</head>
      <div2 id="sec-cvsLog-meat">
	<pre>
$Log: Overview.xml,v $
Revision 1.60  2011/03/03 18:26:31  eric
- "#_"

Revision 1.59  2011/01/08 15:19:00  eric
- Hierarchical Tables

Revision 1.58  2011/01/08 15:02:45  eric
~ rolled back to pre-collaborative version

Revision 1.57  2010/11/10 14:47:28  marenas
Removing "(Editor)" from the list of authors

Revision 1.56  2010/11/10 02:47:08  eric
~ well-formedness error

Revision 1.55  2010/11/10 02:45:37  eric
~ finished adopting the all-relative-IRI model in order to sync with the merged text from alt/
~ adopted "direct" mapping per the resolution of the 2010-11-09 telecon
~ made Juan and Marcello editors instead of authors
~ fixed a couple typos
: I believe this specification follows the intent of:
  RESOLUTION: http://www.w3.org/2001/sw/rdb2rdf/directMapping/ with Juan,
  Marcelo and Eric as editors based on Richard's proposal as of
  http://lists.w3.org/Archives/Public/public-rdb2rdf-wg/2010Nov/0052.html and
  try to work in J&amp;M's IRI and Triple generations part; move hierarchical
  table and the M-M mappings into Ed note; datalog as a separate section; Eric
  perform merge with review/approval/consensus of Juan, Marcelo, &amp; Eric

Revision 1.54  2010/11/09 22:46:56  eric
+ <a href="#hier-table-at-risk">hier-table-at-risk issue</a>

Revision 1.53  2010/11/09 22:41:02  eric
~ date

Revision 1.52  2010/11/09 22:39:12  eric
~ s/stem/base/g
+ inclusion of collapsible sections from alt/

Revision 1.51  2010/11/09 15:39:46  eric
~ removed collapsible sections per request mid:AANLkTikvnrgXuu5fDAw+c2nUv5ENkmngPAJJ05c2gASk@mail.gmail.com

Revision 1.50  2010/11/09 15:06:34  eric
+ exp sections

Revision 1.49  2010/11/09 14:12:08  eric
~ addressed <a href="http://www.w3.org/mid/03EDA176-4DFB-4251-B5F0-3CD73A7D1D52@cyganiak.de">cygri's comments of 2010-11-09T06:46:12Z</a>

Revision 1.48  2010/11/09 04:11:35  eric
~ addressed <a href="http://www.w3.org/mid/3AB73FFE-1FF7-429C-9AB6-1E38E4281273@cyganiak.de">cygri's comments of 2010-11-07T04:13Z</a>
+ inclusion of some explanatory details from <a href="alt">alt</a>

Revision 1.47  2010/11/04 12:42:21  eric
~ working on style for editorial choices

Revision 1.46  2010/11/04 06:10:08  eric
~ hilit triples in query in Use of Direct Mapping

Revision 1.45  2010/11/04 05:42:55  eric
~ incorporated <a href="http://www.w3.org/mid/88769680-C75B-4DF5-B613-78F4D56A6965@cyganiak.de">Richard Cyganiak's comments</a> targeted at <a href="alt">alt</a>

Revision 1.44  2010/11/02 08:18:07  eric
~ updates per DanC's feedback

Revision 1.43  2010/10/29 03:10:12  eric
~ s/relational terminology/SQL terminology/

Revision 1.42  2010/10/17 13:46:48  eric
+ SQL constraints

Revision 1.41  2010/10/12 14:21:36  eric
~ renumbered

Revision 1.40  2010/10/12 12:14:52  eric
+ SQL for example 1

Revision 1.39  2010/10/11 03:12:21  eric
~ prettied up mutual-hilights

Revision 1.38  2010/10/10 22:09:55  eric
+ pfkexception

Revision 1.37  2010/10/10 14:25:41  eric
~ re-worked front-loaded informative rules

Revision 1.36  2010/10/10 11:59:01  eric
~ prettied-up pre@class=turtle
~ experimenting with new presentation of transformation rules
~ validated XSLT output

Revision 1.35  2010/10/09 15:12:40  eric
+ crosslinks for hier-tabl

Revision 1.34  2010/10/09 14:52:31  eric
+ crosslinks for ref-no-pk

Revision 1.33  2010/10/09 13:45:17  eric
~ symmetric xrefs between tables and triples for emp-addr and multi-key

Revision 1.32  2010/10/08 21:59:54  eric
+ hilights

Revision 1.31  2010/09/29 19:53:37  eric
~ align with https://dvcs.w3.org/hg/stemGraph/

Revision 1.30  2010/09/29 15:13:18  eric
~ align with https://dvcs.w3.org/hg/stemGraph/rev/75cf39ef7d74

Revision 1.29  2010/09/29 03:34:55  eric
+ 2nd gen hierarchical example

Revision 1.28  2010/09/28 03:10:53  eric
validation

Revision 1.27  2010/09/28 03:08:52  eric
+ hierarchical (untested)

Revision 1.26  2010/09/27 21:49:18  eric
~ XML validation (per xsltproc)

Revision 1.25  2010/09/27 21:46:42  eric
~ fixed reference table name

Revision 1.24  2010/09/27 18:48:46  eric
+ noticed another key in ref-no-pk

Revision 1.23  2010/09/27 18:13:03  eric
+ ref-no-pk

Revision 1.22  2010/09/27 14:50:44  eric
+ nodemap
+ a rough pass on &lt;scala&gt;scala code&lt;/scala&gt;

Revision 1.21  2010/09/26 04:50:07  eric
~ fix load state for syntax display

Revision 1.20  2010/09/25 18:40:39  eric
+ some tips

Revision 1.19  2010/09/24 16:34:02  eric
+ some tips

Revision 1.18  2010/09/24 16:00:53  eric
+ some tips

Revision 1.17  2010/09/24 15:50:41  eric
+ buttons for different languages

Revision 1.16  2010/09/07 12:14:44  eric
~ fixed pk invocation errors per  mid:04C1B62C-42A5-424C-974B-6E894ED7B11A@cyganiak.de

Revision 1.15  2010/08/30 18:37:19  eric
+ <a href="#no-pk">Empty (Non-existent) Primary Keys</a> section

Revision 1.14  2010/08/30 14:05:45  eric
+ fks

Revision 1.13  2010/08/30 13:27:01  eric
~ content-free prettying-up

Revision 1.12  2010/08/23 14:24:22  eric
~ simplified per Richard's suggestions

Revision 1.11  2010/07/18 21:33:21  eric
~ proof-reading for an <a href="http://www.w3.org/mid/20100718213135.GC18491@w3.org">explanatory email</a>

Revision 1.10  2010/07/12 23:15:42  eric
~ typos revealed when geeking with Sandro

Revision 1.9  2010/06/15 15:23:43  eric
~ validating

Revision 1.8  2010/06/15 14:33:59  eric
~ s/Heading/Header/ per <a href="http://www.googlefight.com/index.php?lang=en_GB&amp;word1=relational+heading&amp;word2=relational+header">google fight</a>

Revision 1.7  2010/06/15 14:27:08  eric
~ s/∀/∣/g per cygri's comment

Revision 1.6  2010/06/07 15:49:34  eric
+ <a href="#extend">Extending the Direct Mapping</a> section

Revision 1.5  2010/06/07 14:35:18  eric
+ finished mappings

Revision 1.4  2010/06/03 23:02:58  eric
~ SNAPSHOT

Revision 1.3  2010/06/03 13:06:00  eric
+ start on literal map

Revision 1.2  2010/06/03 12:43:30  eric
~ made algebra all symboly

Revision 1.1  2010/06/02 15:03:34  eric
CREATED

	</pre>
      </div2>
    </div1>
  </back>
</spec>
       
