+ friendly SPARQL to SQL tests
authorEric Prud'hommeaux <eric@w3.org>
Sun, 14 Feb 2010 07:53:30 -0500
changeset 167 23a6870f1c3f
parent 166 5326978aaa16
child 168 e6fb4674eaec
+ friendly SPARQL to SQL tests
src/test/scala/SparqlToSparqlToSqlTest.scala
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/SparqlToSparqlToSqlTest.scala	Sun Feb 14 07:53:30 2010 -0500
@@ -0,0 +1,475 @@
+/* SparqlToSparqlToSqlTest: transform SPARQL to Stem to SQL and compare against a reference query.
+ * $Id$
+ */
+
+package w3c.sw
+
+import org.scalatest.FunSuite
+import java.net.URI
+import w3c.sw.sparql.Sparql
+import w3c.sw.sparql2sparql.{SparqlToSparql}
+import w3c.sw.sql.{Sql,DatabaseDesc,Relation,RelationDesc,Attribute,Value,Datatype,ForeignKey,Name}
+import w3c.sw.sparql2sql.{SparqlToSql,StemURI}
+
+/* The SparqlToSparqlTest class transforms SPARQL queries to a relational data
+ * structure and compares them to a structure parsed from SQL.
+ */
+class SparqlToSparqlToSqlTest extends FunSuite {
+
+  val hosp1:DatabaseDesc = DatabaseDesc(
+    Map(Relation("Person") -> 
+	RelationDesc(Option(Attribute("ID")), 
+		     Map(Attribute("ID") -> Value(Datatype.INTEGER),
+			 Attribute("MiddleName") -> Value(Datatype.STRING),
+			 Attribute("DateOfBirth") -> Value(Datatype.DATE),
+			 Attribute("SexDE") -> ForeignKey(Relation("Sex_DE"), Attribute("ID")))),
+	Relation("Sex_DE") -> 
+	RelationDesc(Option(Attribute("ID")),
+		     Map(Attribute("ID") -> Value(Datatype.INTEGER),
+			 Attribute("EntryName") -> Value(Datatype.STRING))),
+	Relation("Item_Medication") -> 
+	RelationDesc(Option(Attribute("ID")),
+		     Map(Attribute("ID") -> Value(Datatype.INTEGER),
+			 Attribute("PatientID") -> ForeignKey(Relation("Person"),  Attribute("ID")),
+			 Attribute("PerformedDTTM") -> Value(Datatype.DATE),
+			 Attribute("EntryName") -> Value(Datatype.STRING))),
+	Relation("Medication") -> 
+	RelationDesc(Option(Attribute("ID")),
+		     Map(Attribute("ID") -> Value(Datatype.INTEGER),
+			 Attribute("ItemID") -> ForeignKey(Relation("Item_Medication"),  Attribute("ID")),
+			 Attribute("MedDictDE") -> ForeignKey(Relation("Medication_DE"), Attribute("ID")))),
+	Relation("Medication_DE") -> 
+	RelationDesc(Option(Attribute("ID")),
+		     Map(Attribute("ID") -> Value(Datatype.INTEGER),
+			 Attribute("NDC") -> Value(Datatype.INTEGER))),
+	Relation("NDCcodes") -> 
+	RelationDesc(Option(Attribute("ID")),
+		     Map(Attribute("ID") -> Value(Datatype.INTEGER),
+			 Attribute("NDC") -> Value(Datatype.INTEGER),
+			 Attribute("ingredient") -> Value(Datatype.INTEGER)))
+      ))
+
+  test("~/swobjects/tests/healthCare/lists-notBound/hl7.rq short") {
+    val sparqlParser = Sparql()
+    val hl7Query = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX hl7: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#> 
+SELECT ?patient ?dob ?sex
+WHERE
+{
+  ?patient a hl7:Person .
+  ?patient hl7:entityName ?middleName .
+  ?patient hl7:livingSubjectBirthTime ?dob .
+  ?patient hl7:administrativeGenderCodePrintName ?sex .
+  ?patient hl7:substanceAdministration ?subs_admin .
+  ?subs_admin a hl7:SubstanceAdministration .
+  ?subs_admin hl7:consumable ?consumable .
+  ?consumable hl7:displayName ?takes .
+  ?consumable hl7:activeIngredient ?ingredient .
+  ?ingredient hl7:classCode 6809 .
+  ?subs_admin hl7:effectiveTime ?indic_span .
+}""").get
+
+    val db2hl7 = sparqlParser.parseAll(sparqlParser.construct, """
+PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
+PREFIX Person: <http://hospital.example/DB/Person#>
+PREFIX Sex_DE: <http://hospital.example/DB/Sex_DE#>
+PREFIX Item_Medication: <http://hospital.example/DB/Item_Medication#>
+PREFIX Medication: <http://hospital.example/DB/Medication#>
+PREFIX Medication_DE: <http://hospital.example/DB/Medication_DE#>
+PREFIX NDCcodes: <http://hospital.example/DB/NDCcodes#>
+
+PREFIX hl7: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#>
+PREFIX spl: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#>
+
+CONSTRUCT {
+?person     a					  hl7:Person .
+?person     hl7:entityName			  ?middleName .
+?person     hl7:livingSubjectBirthTime		  ?dob .
+?person     hl7:administrativeGenderCodePrintName ?sex .
+?person     hl7:substanceAdministration		  ?subst .
+?subst	a	       hl7:SubstanceAdministration .
+?subst 	hl7:consumable ?cons .
+?cons	    hl7:displayName	 ?takes .
+?cons	    spl:activeIngredient ?ingred .
+?ingred		spl:classCode ?ingredCode .
+?subst	hl7:effectiveTime ?interval .
+?interval	    hl7:start ?indicDate 
+} WHERE {
+  ?person     Person:MiddleName		     ?middleName .
+  ?person     Person:DateOfBirth	     ?dob .
+  ?person     Person:SexDE		     ?sexEntry   .
+
+              ?sexEntry   Sex_DE:EntryName   ?sex .
+
+  ?indicItem  Item_Medication:PatientID	     ?person .
+  ?indicItem  Item_Medication:PerformedDTTM  ?indicDate .
+  ?indicItem  Item_Medication:EntryName	     ?takes .
+  ?indicMed   Medication:ItemID		     ?indicItem .
+  ?indicMed   Medication:DaysToTake	     ?indicDuration .
+  ?indicMed   Medication:MedDictDE	     ?indicDE .
+  ?indicDE    Medication_DE:NDC		     ?indicNDC .
+  ?indicCode  NDCcodes:NDC         ?indicNDC .
+  ?indicCode  NDCcodes:ingredient  ?ingredCode }
+""").get
+    val stemQuery = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX Person: <http://hospital.example/DB/Person#>
+PREFIX Sex_DE: <http://hospital.example/DB/Sex_DE#>
+PREFIX Item_Medication: <http://hospital.example/DB/Item_Medication#>
+PREFIX Medication: <http://hospital.example/DB/Medication#>
+PREFIX Medication_DE: <http://hospital.example/DB/Medication_DE#>
+PREFIX NDCcodes: <http://hospital.example/DB/NDCcodes#>
+PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
+
+SELECT ?patient ?dob ?sex
+ WHERE {
+    ?patient Person:MiddleName ?middleName .
+    ?patient Person:DateOfBirth ?dob .
+    ?patient Person:SexDE ?_0_sexEntry .
+    ?_0_sexEntry Sex_DE:EntryName ?sex .
+
+    ?_0_indicItem Item_Medication:PatientID ?patient .
+    ?_0_indicItem Item_Medication:EntryName ?takes .
+    ?_0_indicMed Medication:ItemID ?_0_indicItem .
+    ?_0_indicMed Medication:MedDictDE ?_0_indicDE .
+    ?_0_indicDE Medication_DE:NDC ?_0_indicNDC .
+    ?_0_indicCode NDCcodes:NDC ?_0_indicNDC .
+    ?_0_indicCode NDCcodes:ingredient 6809
+}
+""").get
+    val asStem = SparqlToSparql(hl7Query, List(db2hl7))
+    assert(asStem === stemQuery)
+    val sqlParser = Sql()
+    val sqlQuery = sqlParser.parseAll(sqlParser.select, """
+SELECT R_patient.ID AS patient, R_patient.DateOfBirth AS dob, R__0_sexEntry.EntryName AS sex
+  FROM Person AS R_patient
+       INNER JOIN Sex_DE AS R__0_sexEntry ON R__0_sexEntry.ID=R_patient.SexDE
+       INNER JOIN Item_Medication AS R__0_indicItem ON R__0_indicItem.PatientID=R_patient.ID
+       INNER JOIN Medication AS R__0_indicMed ON R__0_indicMed.ItemID=R__0_indicItem.ID
+       INNER JOIN Medication_DE AS R__0_indicDE ON R__0_indicDE.ID=R__0_indicMed.MedDictDE
+       INNER JOIN NDCcodes AS R__0_indicCode ON R__0_indicCode.NDC=R__0_indicDE.NDC
+ WHERE R__0_indicCode.ingredient=6809
+   AND R__0_sexEntry.ID=R_patient.SexDE
+   AND R__0_indicItem.EntryName IS NOT NULL
+   AND R_patient.DateOfBirth IS NOT NULL
+   AND R_patient.MiddleName IS NOT NULL
+   AND R__0_sexEntry.EntryName IS NOT NULL
+""").get
+    val asSql = SparqlToSql(hosp1, stemQuery, StemURI("http://hospital.example/DB/"), false, false)
+    assert(asSql === sqlQuery)
+    val output = """
+"""
+  }
+
+  test("~/swobjects/tests/healthCare/lists-notBound/hl7.rq MINUS") {
+    val sparqlParser = Sparql()
+    val hl7Query = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX hl7: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#> 
+SELECT ?patient ?dob ?sex ?inclu_name ?indicDate 
+WHERE
+{
+  ?patient a hl7:Person .
+  ?patient hl7:entityName ?middleName .
+  ?patient hl7:livingSubjectBirthTime ?dob .
+  ?patient hl7:administrativeGenderCodePrintName ?sex .
+  ?patient hl7:substanceAdministration ?inclu_subs .
+  ?inclu_subs a hl7:SubstanceAdministration .
+  ?inclu_subs hl7:consumable ?inclu_consu .
+  ?inclu_consu hl7:displayName ?inclu_name .
+  ?inclu_consu hl7:activeIngredient ?inclu_intred .
+  ?inclu_intred hl7:classCode 6809 .
+  ?inclu_subs hl7:effectiveTime ?inclu_span .
+  MINUS {
+    ?patient hl7:substanceAdministration ?exclu_subs .
+    ?exclu_subs a hl7:SubstanceAdministration .
+    ?exclu_subs hl7:consumable ?exclu_consu .
+    ?exclu_consu hl7:displayName ?exclu_name .
+    ?exclu_consu hl7:activeIngredient ?exclu_intred .
+    ?exclu_intred hl7:classCode 11209 .
+    ?exclu_subs hl7:effectiveTime ?exclu_span .
+  }
+}""").get
+
+    val db2hl7 = sparqlParser.parseAll(sparqlParser.construct, """
+PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
+PREFIX Person: <http://hospital.example/DB/Person#>
+PREFIX Sex_DE: <http://hospital.example/DB/Sex_DE#>
+PREFIX Item_Medication: <http://hospital.example/DB/Item_Medication#>
+PREFIX Medication: <http://hospital.example/DB/Medication#>
+PREFIX Medication_DE: <http://hospital.example/DB/Medication_DE#>
+PREFIX NDCcodes: <http://hospital.example/DB/NDCcodes#>
+
+PREFIX hl7: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#>
+PREFIX spl: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#>
+
+CONSTRUCT {
+?person     a					  hl7:Person .
+?person     hl7:entityName			  ?middleName .
+?person     hl7:livingSubjectBirthTime		  ?dob .
+?person     hl7:administrativeGenderCodePrintName ?sex .
+?person     hl7:substanceAdministration		  ?subst .
+?subst	a	       hl7:SubstanceAdministration .
+?subst 	hl7:consumable ?cons .
+?cons	    hl7:displayName	 ?takes .
+?cons	    spl:activeIngredient ?ingred .
+?ingred		spl:classCode ?ingredCode .
+?subst	hl7:effectiveTime ?interval .
+?interval	    hl7:start ?indicDate 
+} WHERE {
+  ?person     Person:MiddleName		     ?middleName .
+  ?person     Person:DateOfBirth	     ?dob .
+  ?person     Person:SexDE		     ?sexEntry   .
+
+              ?sexEntry   Sex_DE:EntryName   ?sex .
+
+  ?indicItem  Item_Medication:PatientID	     ?person .
+  ?indicItem  Item_Medication:PerformedDTTM  ?indicDate .
+  ?indicItem  Item_Medication:EntryName	     ?takes .
+  ?indicMed   Medication:ItemID		     ?indicItem .
+  ?indicMed   Medication:DaysToTake	     ?indicDuration .
+  ?indicMed   Medication:MedDictDE	     ?indicDE .
+  ?indicDE    Medication_DE:NDC		     ?indicNDC .
+  ?indicCode  NDCcodes:NDC         ?indicNDC .
+  ?indicCode  NDCcodes:ingredient  ?ingredCode }
+""").get
+    val stemQuery = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX Person: <http://hospital.example/DB/Person#>
+PREFIX Sex_DE: <http://hospital.example/DB/Sex_DE#>
+PREFIX Item_Medication: <http://hospital.example/DB/Item_Medication#>
+PREFIX Medication: <http://hospital.example/DB/Medication#>
+PREFIX Medication_DE: <http://hospital.example/DB/Medication_DE#>
+PREFIX NDCcodes: <http://hospital.example/DB/NDCcodes#>
+PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
+
+SELECT ?patient
+ WHERE {
+    ?patient Person:MiddleName ?middleName .
+    ?patient Person:DateOfBirth ?dob .
+    ?patient Person:SexDE ?_0_sexEntry .
+    ?_0_sexEntry Sex_DE:EntryName ?sex .
+
+    ?_0_indicItem Item_Medication:PatientID ?patient .
+    ?_0_indicItem Item_Medication:PerformedDTTM ?indicDate .
+    ?_0_indicItem Item_Medication:EntryName ?takes .
+    ?_0_indicMed Medication:ItemID ?_0_indicItem .
+    ?_0_indicMed Medication:MedDictDE ?_0_indicDE .
+    ?_0_indicDE Medication_DE:NDC ?indicNDC .
+    ?_0_indicCode NDCcodes:NDC ?indicNDC .
+    ?_0_indicCode NDCcodes:ingredient 6809
+
+    MINUS {
+        ?disqualItem Item_Medication:PatientID ?patient .
+        ?disqualItem Item_Medication:PerformedDTTM ?disqualDate .
+        ?disqualItem Item_Medication:EntryName ?takes .
+        ?disqualMed Medication:ItemID ?disqualItem .
+        ?disqualMed Medication:MedDictDE ?disqualDE .
+        ?disqualDE Medication_DE:NDC ?disqualNDC .
+        ?disqualCode NDCcodes:NDC ?disqualNDC .
+        ?disqualCode NDCcodes:ingredient 11289
+    }
+      }
+""").get
+    val sqlParser = Sql()
+    val sqlQuery = sqlParser.parseAll(sqlParser.select, """
+SELECT R_patient.ID AS patient, R_patient.DateOfBirth AS dob, R__0_sexEntry.EntryName AS sex
+  FROM Person AS R_patient
+       INNER JOIN Sex_DE AS R__0_sexEntry ON R__0_sexEntry.ID=R_patient.SexDE
+       INNER JOIN Item_Medication AS R__0_indicItem ON R__0_indicItem.PatientID=R_patient.ID
+       INNER JOIN Medication AS R__0_indicMed ON R__0_indicMed.ItemID=R__0_indicItem.ID
+       INNER JOIN Medication_DE AS R__0_indicDE ON R__0_indicDE.ID=R__0_indicMed.MedDictDE
+       INNER JOIN NDCcodes AS R__0_indicCode ON R__0_indicCode.NDC=R__0_indicDE.NDC
+       LEFT OUTER JOIN (
+   SELECT R_disqualCode.ID AS disqualCode, R_disqualMed.MedDictDE AS disqualDE,
+          R_disqualItem.PerformedDTTM AS disqualDate, R_disqualItem.ID AS disqualItem,
+          R_disqualMed.ID AS disqualMed, R_disqualDE.NDC AS disqualNDC,
+          R_disqualItem.PatientID AS patient, R_disqualItem.EntryName AS takes, 6 AS _DISJOINT_
+     FROM Item_Medication AS R_disqualItem
+          INNER JOIN Medication AS R_disqualMed ON R_disqualMed.ItemID=R_disqualItem.ID
+          INNER JOIN Medication_DE AS R_disqualDE ON R_disqualDE.ID=R_disqualMed.MedDictDE
+          INNER JOIN NDCcodes AS R_disqualCode ON R_disqualCode.NDC=R_disqualDE.NDC
+    WHERE R_disqualCode.ingredient=11289
+      AND R_disqualItem.EntryName IS NOT NULL
+      AND R_disqualItem.PatientID IS NOT NULL
+      AND R_disqualItem.PerformedDTTM IS NOT NULL
+              ) AS G_opt6 ON G_opt6.patient=R_patient.ID
+                         AND G_opt6.takes=R_indicItem.EntryName
+ WHERE G_opt6._DISJOINT_ IS NULL
+   AND R__0_indicCode.ingredient=6809
+   AND R__0_sexEntry.ID=R_patient.SexDE
+   AND R__0_indicItem.EntryName IS NOT NULL
+   AND R_patient.DateOfBirth IS NOT NULL
+   AND R_patient.MiddleName IS NOT NULL
+   AND R__0_sexEntry.EntryName IS NOT NULL
+""").get
+    val asStem = SparqlToSparql(hl7Query, List(db2hl7))
+    if (!(asStem == stemQuery)) {
+      println(asStem.toString())
+      println("---")
+      println(stemQuery.toString())
+    }
+    assert(asStem == stemQuery)
+    val asSql = SparqlToSql(hosp1, asStem, StemURI("http://hospital.example/DB/"), false, false)
+    assert(asSql === sqlQuery)
+    val output = """
+"""
+  }
+
+//   test("~/swobjects/tests/healthCare/lists-notBound/hl7.rq") {
+//     val sparqlParser = Sparql()
+//     val hl7Query = sparqlParser.parseAll(sparqlParser.select, """
+// PREFIX hl7: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#> 
+// SELECT ?patient ?dob ?sex ?takes ?indicDate 
+// WHERE
+// {
+//   {
+//     ?patient a hl7:Person .
+//     ?patient hl7:entityName ?middleName .
+//     ?patient hl7:livingSubjectBirthTime ?dob .
+//     ?patient hl7:administrativeGenderCodePrintName ?sex .
+//     ?patient hl7:substanceAdministration ?subs_admin .
+//     ?subs_admin a hl7:SubstanceAdministration .
+//     ?subs_admin hl7:consumable ?consumable .
+//     ?consumable hl7:displayName ?takes .
+//     ?consumable hl7:activeIngredient ?ingredient .
+//     ?ingredient hl7:classCode ?code .
+//     ?subs_admin hl7:effectiveTime ?indic_span .
+//     ?indic_span hl7:start ?indicDate .
+//     FILTER ( ?code = 6809 )
+//   }
+//   MINUS {
+//     ?b0x8ea18a8_gen4 a hl7:SubstanceAdministration .
+//     ?b0x8ea1a58_gen1 hl7:displayName ?takes_gen1 .
+//     ?b0x8ea1f30_gen2 hl7:classCode ?contCode .
+//     ?b0x8ea1a58_gen1 hl7:activeIngredient ?b0x8ea1f30_gen2 .
+//     ?b0x8ea18a8_gen4 hl7:consumable ?b0x8ea1a58_gen1 .
+//     ?b0x8ea17f0_gen3 hl7:start ?indicDate .
+//     ?b0x8ea18a8_gen4 hl7:effectiveTime ?b0x8ea17f0_gen3 .
+//     ?patient hl7:substanceAdministration ?b0x8ea18a8_gen4 .
+//     FILTER ( ?contCode = 11289 )
+//   }
+// }""").get
+
+//     val db2hl7 = sparqlParser.parseAll(sparqlParser.construct, """
+// PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
+// PREFIX Person: <http://hospital.example/DB/Person#>
+// PREFIX Sex_DE: <http://hospital.example/DB/Sex_DE#>
+// PREFIX Item_Medication: <http://hospital.example/DB/Item_Medication#>
+// PREFIX Medication: <http://hospital.example/DB/Medication#>
+// PREFIX Medication_DE: <http://hospital.example/DB/Medication_DE#>
+// PREFIX NDCcodes: <http://hospital.example/DB/NDCcodes#>
+
+// PREFIX hl7: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#>
+// PREFIX spl: <http://www.hl7.org/v3ballot/xml/infrastructure/vocabulary/vocabulary#>
+
+// CONSTRUCT {
+// ?person     a					  hl7:Person .
+// ?person     hl7:entityName			  ?middleName .
+// ?person     hl7:livingSubjectBirthTime		  ?dob .
+// ?person     hl7:administrativeGenderCodePrintName ?sex .
+// ?person     hl7:substanceAdministration		  ?subst .
+// ?subst	a	       hl7:SubstanceAdministration .
+// ?subst 	hl7:consumable ?cons .
+// ?cons	    hl7:displayName	 ?takes .
+// ?cons	    spl:activeIngredient ?ingred .
+// ?ingred		spl:classCode ?ingredCode .
+// ?subst	hl7:effectiveTime ?interval .
+// ?interval	    hl7:start ?indicDate 
+// } WHERE {
+//   ?person     Person:MiddleName		     ?middleName .
+//   ?person     Person:DateOfBirth	     ?dob .
+//   ?person     Person:SexDE		     ?sexEntry   .
+
+//               ?sexEntry   Sex_DE:EntryName   ?sex .
+
+//   ?indicItem  Item_Medication:PatientID	     ?person .
+//   ?indicItem  Item_Medication:PerformedDTTM  ?indicDate .
+//   ?indicItem  Item_Medication:EntryName	     ?takes .
+//   ?indicMed   Medication:ItemID		     ?indicItem .
+//   ?indicMed   Medication:DaysToTake	     ?indicDuration .
+//   ?indicMed   Medication:MedDictDE	     ?indicDE .
+//   ?indicDE    Medication_DE:NDC		     ?indicNDC .
+//   ?indicCode  NDCcodes:NDC         ?indicNDC .
+//   ?indicCode  NDCcodes:ingredient  ?ingredCode }
+// """).get
+//     val stemQuery = sparqlParser.parseAll(sparqlParser.select, """
+// PREFIX Person: <http://hospital.example/DB/Person#>
+// PREFIX Sex_DE: <http://hospital.example/DB/Sex_DE#>
+// PREFIX Item_Medication: <http://hospital.example/DB/Item_Medication#>
+// PREFIX Medication: <http://hospital.example/DB/Medication#>
+// PREFIX Medication_DE: <http://hospital.example/DB/Medication_DE#>
+// PREFIX NDCcodes: <http://hospital.example/DB/NDCcodes#>
+// PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
+
+// SELECT ?patient
+//  WHERE {
+//     ?patient Person:MiddleName ?middleName .
+//     ?patient Person:DateOfBirth ?dob .
+//     ?patient Person:SexDE ?_0_sexEntry .
+//     ?_0_sexEntry Sex_DE:EntryName ?sex .
+
+//     ?_0_indicItem Item_Medication:PatientID ?patient .
+//     ?_0_indicItem Item_Medication:PerformedDTTM ?indicDate .
+//     ?_0_indicItem Item_Medication:EntryName ?takes .
+//     ?_0_indicMed Medication:ItemID ?_0_indicItem .
+//     ?_0_indicMed Medication:MedDictDE ?_0_indicDE .
+//     ?_0_indicDE Medication_DE:NDC ?indicNDC .
+//     ?_0_indicCode NDCcodes:NDC ?indicNDC .
+//     ?_0_indicCode NDCcodes:ingredient 6809
+
+//     MINUS {
+//         ?disqualItem Item_Medication:PatientID ?patient .
+//         ?disqualItem Item_Medication:PerformedDTTM ?disqualDate .
+//         ?disqualItem Item_Medication:EntryName ?takes .
+//         ?disqualMed Medication:ItemID ?disqualItem .
+//         ?disqualMed Medication:MedDictDE ?disqualDE .
+//         ?disqualDE Medication_DE:NDC ?disqualNDC .
+//         ?disqualCode NDCcodes:NDC ?disqualNDC .
+//         ?disqualCode NDCcodes:ingredient 11289
+//     }
+//       }
+// """).get
+//     val sqlParser = Sql()
+//     val sqlQuery = sqlParser.parseAll(sqlParser.select, """
+// SELECT R_patient.ID AS patient
+//   FROM Person AS R_patient
+//        INNER JOIN Sex_DE AS R_sexEntry ON R_sexEntry.ID=R_patient.SexDE
+//        INNER JOIN Item_Medication AS R_indicItem ON R_indicItem.PatientID=R_patient.ID
+//        INNER JOIN Medication AS R__0_indicMed ON R__0_indicMed.ItemID=R_indicItem.ID
+//        INNER JOIN Medication_DE AS R__0_indicDE ON R__0_indicDE.ID=R__0_indicMed.MedDictDE
+//        INNER JOIN NDCcodes AS R__0_indicCode ON R__0_indicCode.NDC=R__0_indicDE.NDC
+//        LEFT OUTER JOIN (
+//    SELECT R_disqualCode.ID AS disqualCode, R_disqualMed.MedDictDE AS disqualDE,
+//           R_disqualItem.PerformedDTTM AS disqualDate, R_disqualItem.ID AS disqualItem,
+//           R_disqualMed.ID AS disqualMed, R_disqualDE.NDC AS disqualNDC,
+//           R_disqualItem.PatientID AS patient, R_disqualItem.EntryName AS takes, 6 AS _DISJOINT_
+//      FROM Item_Medication AS R_disqualItem
+//           INNER JOIN Medication AS R_disqualMed ON R_disqualMed.ItemID=R_disqualItem.ID
+//           INNER JOIN Medication_DE AS R_disqualDE ON R_disqualDE.ID=R_disqualMed.MedDictDE
+//           INNER JOIN NDCcodes AS R_disqualCode ON R_disqualCode.NDC=R_disqualDE.NDC
+//     WHERE R_disqualCode.ingredient=11289
+//       AND R_disqualItem.EntryName IS NOT NULL
+//       AND R_disqualItem.PatientID IS NOT NULL
+//       AND R_disqualItem.PerformedDTTM IS NOT NULL
+//               ) AS G_opt6 ON G_opt6.patient=R_patient.ID
+//                          AND G_opt6.takes=R_indicItem.EntryName
+//  WHERE G_opt6._DISJOINT_ IS NULL
+//    AND R__0_indicCode.ingredient=6809
+//    AND R_indicItem.EntryName IS NOT NULL
+//    AND R_indicItem.PerformedDTTM IS NOT NULL
+//    AND R_patient.DateOfBirth IS NOT NULL
+//    AND R_patient.MiddleName IS NOT NULL
+//    AND R_sexEntry.EntryName IS NOT NULL
+// """).get
+//     val asStem = SparqlToSparql(hl7Query, List(db2hl7))
+//     if (!(asStem == stemQuery)) {
+//       println(asStem.toString())
+//       println("---")
+//       println(stemQuery.toString())
+//     }
+//     assert(asStem == stemQuery)
+//     val asSql = SparqlToSql(hosp1, asStem, StemURI("http://hospital.example/DB/"), false, false)
+//     assert(asSql === sqlQuery)
+//     val output = """
+// """
+//   }
+
+}