- a parm to varConstraint
authorEric Prud'hommeaux <eric@w3.org>
Thu, 13 May 2010 11:45:03 -0400
changeset 190 c7bb30e943ab
parent 189 5289beae5a4e
child 191 b402d3939ecb
- a parm to varConstraint
src/main/scala/SparqlToSql.scala
--- a/src/main/scala/SparqlToSql.scala	Mon May 10 06:01:07 2010 -0400
+++ b/src/main/scala/SparqlToSql.scala	Thu May 13 11:45:03 2010 -0400
@@ -231,19 +231,16 @@
    * @param u SparqlToSql URL object, e.g. <code>NodeUri(http://hr.example/DB,Employee,empid,CellValue(18))</code>
    * @return state + expression for the URI
    * <p/>
-   * u:<code>NodeUri(http://hr.example/DB,Employee,empid,CellValue(18)), true</code> =&gt;<code>R_emp.manager=18</code>
-   * u:<code>NodeUri(http://hr.example/DB,Employee,empid,CellValue(18)), false</code> =&gt;<code>R_empid18.empid=18</code>
+   * <code>http://hr.example/DB/Employee/empid=18, true</code> =&gt;<code>R_emp.manager=18</code>
+   * <code>http://hr.example/DB/Employee/empid=18, false</code> =&gt;<code>R_empid18.empid=18</code>
    * (the latter produces another join on R_empid18 in order to enforce a foreign key.)
+   * http://hr.example/DB/Employee/empid=18 has already been parsed to produce a NodeUri:
+   *   NodeUri(http://hr.example/DB,Employee,empid,CellValue(18))
    */
-  def uriConstraint(state:R2RState, constrainMe:sql.RelVarAttr, u:NodeUri, enforceForeignKeys:Boolean):R2RState = {
-    val relvar =
-      if (enforceForeignKeys)
-	sql.RelVarAttr(constrainMe.relvar, sql.Attribute(sql.Name(u.attr.s)))
-      else
-	constrainMe
+  def uriConstraint(state:R2RState, constrainMe:sql.RelVarAttr, u:NodeUri):R2RState = {
     R2RState(state.joins,
 	     state.varmap,
-	     state.exprs + sql.RelationalExpressionEq(sql.PrimaryExpressionAttr(relvar),
+	     state.exprs + sql.RelationalExpressionEq(sql.PrimaryExpressionAttr(constrainMe),
 						      sql.PrimaryExpressionTyped(sql.Datatype.INTEGER,sql.Name(u.v.s))))
   }
 
@@ -289,7 +286,7 @@
      * Bind optAttr to an SQL generator like RDFNoder(Employee,FullBinding(R_emp.empid))
      */
     val binding = reldesc.primarykey match {
-      /** <pre>varConstraint(R_emp, Some(empid), VarAssignable(?emp), Employee) -> RDFNoder(Employee,FullBinding(R_emp.empid))</pre> */
+      /** <pre>varConstraint(R_emp, Some(empid), VarAssignable(?emp), Employee) -&gt; RDFNoder(Employee,FullBinding(R_emp.empid))</pre> */
       case Some(sql.Attribute(constrainMe.attribute.n)) => RDFNoder(rel, boundTo)
       case _ => {
 
@@ -358,28 +355,48 @@
   //   }
   // }
 
-  /* bindOnPredicate: map a given triple to one or two joined tables, variable
+  /**
+   * map a given triple to one or two joined tables, variable
+   * @param db  database description
+   * @param stateP  earlier R2RState
+   * @param triple  
+   * @param enforceForeignKeys  
+   * @return a new R2RState incorporating the new binding
    * bindings to RelVarAttrs, and constraints if those variables were
    * already bound. */
   def bindOnPredicate(db:sql.DatabaseDesc, stateP:R2RState, triple:sparql.TriplePattern, enforceForeignKeys:Boolean):R2RState = {
     val sparql.TriplePattern(s, p, o) = triple
     p match {
+      /** Don't deal with ?s ?p ?o . We could deal with <s> ?p ?o , but haven't yet. */
       case sparql.TermVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
       case sparql.TermUri(uri) => {
 	val PUri(stem, spRel, spAttr) = parsePredicateURI(uri)
-	/* Attributes that come from the predicate: */
+	/** The relation and attribute come from the predicate, e.g. Employee.fname =&gt; Employee and fname. */
 	val rel = sql.Relation(sql.Name(spRel.s))
 	val attr = sql.Attribute(sql.Name(spAttr.s))
-	val relvar = relVarFromTerm(s)
 
-	/* Attributes that come from the subject: */
+	/**
+	 * The particular join for e.g. Employee is controled by the subject.
+	 * ?emp =&gt; Employee AS emp
+	 * <Employee:18> =&gt; Employee AS Employee_18 .
+         */
+	val relvar = relVarFromTerm(s)
+	/** Synthesize relvar attribute, e.g. emp.fname. */
 	val objattr = sql.RelVarAttr(relvar, attr)
+
+	/** Accumulate joins and constraints that come from the subject */
 	val state_postSubj = s match {
-	  case sparql.TermUri(u) => uriConstraint(stateP, sql.RelVarAttr(relvar, db.relationdescs(rel).primarykey.get), parseObjectURI(u), true)
-	  case sparql.TermVar(v) => try { varConstraint(stateP, relvar, db.relationdescs(rel).primarykey, sparql.VarAssignable(v), db, rel) } catch {
-	    case e:java.util.NoSuchElementException =>
-	      throw new Exception("error processing { " + s + " " + p + " " + o + " } :db.relationdescs(" + rel + ") not found in " + db)
-	  }
+	  case sparql.TermUri(u) =>
+	    /** additional constraint, e.g. R_empid18.empid=18. */
+	    uriConstraint(stateP, sql.RelVarAttr(relvar, db.relationdescs(rel).primarykey.get), parseObjectURI(u))
+	  case sparql.TermVar(v) =>
+	    try {
+	      varConstraint(stateP, relvar, db.relationdescs(rel).primarykey, sparql.VarAssignable(v), db, rel)
+	    } catch {
+	      case e:java.util.NoSuchElementException =>
+		/** Attribute not found in database description. */
+		throw new Exception("error processing { " + s + " " + p + " " + o + " } :db.relationdescs(" + rel + ") not found in " + db)
+	    }
 	  case sparql.TermBNode(b) => try { varConstraint(stateP, relvar, db.relationdescs(rel).primarykey, sparql.BNodeAssignable(b), db, rel) } catch {
 	    case e:java.util.NoSuchElementException =>
 	      throw new Exception("error processing { " + s + " " + p + " " + o + " } :db.relationdescs(" + rel + ") not found in " + db)
@@ -421,7 +438,7 @@
 	}
 	o match {
 	  case sparql.TermLit(l) => literalConstraint(state_fkeys, targetattr, l, dt)
-	  case sparql.TermUri(u) => uriConstraint    (state_fkeys, targetattr, parseObjectURI(u), enforceForeignKeys)
+	  case sparql.TermUri(u) => uriConstraint    (state_fkeys, targetattr, parseObjectURI(u))
 	  case sparql.TermVar(v) => varConstraint    (state_fkeys, targetattr.relvar, Some(targetattr.attribute), sparql.VarAssignable(v), db, targetrel)
 	  case sparql.TermBNode(b) => varConstraint    (state_fkeys, targetattr.relvar, Some(targetattr.attribute), sparql.BNodeAssignable(b), db, targetrel)
 	}