|
27 | 27 | import org.eclipse.rdf4j.model.vocabulary.FOAF; |
28 | 28 | import org.eclipse.rdf4j.model.vocabulary.RDF; |
29 | 29 | import org.eclipse.rdf4j.model.vocabulary.RDFS; |
| 30 | +import org.eclipse.rdf4j.query.GraphQuery; |
30 | 31 | import org.eclipse.rdf4j.query.Query; |
31 | 32 | import org.eclipse.rdf4j.query.TupleQuery; |
32 | 33 | import org.eclipse.rdf4j.query.explanation.Explanation; |
@@ -101,6 +102,60 @@ public class QueryPlanRetrievalTest { |
101 | 102 | " }\n" + |
102 | 103 | "} GROUP BY ?countryID ?year"; |
103 | 104 |
|
| 105 | + public static final String CONSTRUCT = "PREFIX epo: <http://data.europa.eu/a4g/ontology#>\n" + |
| 106 | + "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n" + |
| 107 | + "PREFIX legal: <https://www.w3.org/ns/legal#>\n" + |
| 108 | + "PREFIX dcterms: <http://purl.org/dc/terms#>\n" + |
| 109 | + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" + |
| 110 | + "PREFIX dc: <http://purl.org/dc/elements/1.1/>\n" + |
| 111 | + "\n" + |
| 112 | + "CONSTRUCT {" + |
| 113 | + "\n" + |
| 114 | + " ?proc a epo:Procedure .\n" + |
| 115 | + " ?proc epo:hasProcedureType ?p .\n" + |
| 116 | + " ?stat epo:concernsSubmissionsForLot ?lot .\n" + |
| 117 | + " ?stat a epo:SubmissionStatisticalInformation .\n" + |
| 118 | + " ?stat epo:hasReceivedTenders ?bidders .\n" + |
| 119 | + " ?resultnotice a epo:ResultNotice .\n" + |
| 120 | + " ?resultnotice epo:hasDispatchDate ?ddate .\n" + |
| 121 | + " ?proc epo:hasProcurementScopeDividedIntoLot ?lot .\n" + |
| 122 | + " ?resultnotice epo:refersToRole ?buyerrole .\n" + |
| 123 | + " ?resultnotice epo:refersToProcedure ?proc .\n" + |
| 124 | + "}" + |
| 125 | + " WHERE {\n" |
| 126 | + + |
| 127 | + "\n" + |
| 128 | + " ?proc a epo:Procedure .\n" + |
| 129 | + " ?proc epo:hasProcedureType ?p .\n" + |
| 130 | + " ?stat epo:concernsSubmissionsForLot ?lot .\n" + |
| 131 | + " ?stat a epo:SubmissionStatisticalInformation .\n" + |
| 132 | + " ?stat epo:hasReceivedTenders ?bidders .\n" + |
| 133 | + " ?resultnotice a epo:ResultNotice .\n" + |
| 134 | + " ?resultnotice epo:hasDispatchDate ?ddate .\n" + |
| 135 | + " ?proc epo:hasProcurementScopeDividedIntoLot ?lot .\n" + |
| 136 | + " ?resultnotice epo:refersToRole ?buyerrole .\n" + |
| 137 | + " ?resultnotice epo:refersToProcedure ?proc .\n" + |
| 138 | + "\n" + |
| 139 | + " \tFILTER ( ?p != <http://publications.europa.eu/resource/authority/procurement-procedure-type/neg-wo-call>)\n" |
| 140 | + + |
| 141 | + "\t\tBIND(year(xsd:dateTime(?ddate)) AS ?year) .\n" + |
| 142 | + "\n" + |
| 143 | + "\n" + |
| 144 | + " {\n" + |
| 145 | + " SELECT DISTINCT ?buyerrole ?countryID WHERE {\n" + |
| 146 | + " ?org epo:hasBuyerType ?buytype .\n" + |
| 147 | + " FILTER (?buytype != <http://publications.europa.eu/resource/authority/buyer-legal-type/eu-int-org> )\n" |
| 148 | + + |
| 149 | + "\n" + |
| 150 | + " ?buyerrole epo:playedBy ?org .\n" + |
| 151 | + " ?org legal:registeredAddress ?orgaddress .\n" + |
| 152 | + " ?orgaddress epo:hasCountryCode ?countrycode .\n" + |
| 153 | + " ?countrycode dc:identifier ?countryID .\n" + |
| 154 | + "\n" + |
| 155 | + " }\n" + |
| 156 | + " }\n" + |
| 157 | + "} GROUP BY ?countryID ?year"; |
| 158 | + |
104 | 159 | public static final String UNION_QUERY = "select ?a where {?a a ?type. {?a ?b ?c, ?c2. {?c2 a ?type1}UNION{?c2 a ?type2}} UNION {?type ?d ?c}}"; |
105 | 160 |
|
106 | 161 | ValueFactory vf = SimpleValueFactory.getInstance(); |
@@ -1534,6 +1589,211 @@ public void testArbitraryLengthPath() { |
1534 | 1589 |
|
1535 | 1590 | } |
1536 | 1591 |
|
| 1592 | + @Test |
| 1593 | + public void constructQueryTest() { |
| 1594 | + |
| 1595 | + String expected = "Reduced\n" + |
| 1596 | + " MultiProjection\n" + |
| 1597 | + " ProjectionElemList\n" + |
| 1598 | + " ProjectionElem \"proc\" AS \"subject\"\n" + |
| 1599 | + " ProjectionElem \"_const_f5e5585a_uri\" AS \"predicate\"\n" + |
| 1600 | + " ProjectionElem \"_const_be18ee7b_uri\" AS \"object\"\n" + |
| 1601 | + " ProjectionElemList\n" + |
| 1602 | + " ProjectionElem \"proc\" AS \"subject\"\n" + |
| 1603 | + " ProjectionElem \"_const_9c756f6b_uri\" AS \"predicate\"\n" + |
| 1604 | + " ProjectionElem \"p\" AS \"object\"\n" + |
| 1605 | + " ProjectionElemList\n" + |
| 1606 | + " ProjectionElem \"stat\" AS \"subject\"\n" + |
| 1607 | + " ProjectionElem \"_const_25686184_uri\" AS \"predicate\"\n" + |
| 1608 | + " ProjectionElem \"lot\" AS \"object\"\n" + |
| 1609 | + " ProjectionElemList\n" + |
| 1610 | + " ProjectionElem \"stat\" AS \"subject\"\n" + |
| 1611 | + " ProjectionElem \"_const_f5e5585a_uri\" AS \"predicate\"\n" + |
| 1612 | + " ProjectionElem \"_const_ea79e75_uri\" AS \"object\"\n" + |
| 1613 | + " ProjectionElemList\n" + |
| 1614 | + " ProjectionElem \"stat\" AS \"subject\"\n" + |
| 1615 | + " ProjectionElem \"_const_98c73a3c_uri\" AS \"predicate\"\n" + |
| 1616 | + " ProjectionElem \"bidders\" AS \"object\"\n" + |
| 1617 | + " ProjectionElemList\n" + |
| 1618 | + " ProjectionElem \"resultnotice\" AS \"subject\"\n" + |
| 1619 | + " ProjectionElem \"_const_f5e5585a_uri\" AS \"predicate\"\n" + |
| 1620 | + " ProjectionElem \"_const_77e914ad_uri\" AS \"object\"\n" + |
| 1621 | + " ProjectionElemList\n" + |
| 1622 | + " ProjectionElem \"resultnotice\" AS \"subject\"\n" + |
| 1623 | + " ProjectionElem \"_const_1b0b00ca_uri\" AS \"predicate\"\n" + |
| 1624 | + " ProjectionElem \"ddate\" AS \"object\"\n" + |
| 1625 | + " ProjectionElemList\n" + |
| 1626 | + " ProjectionElem \"proc\" AS \"subject\"\n" + |
| 1627 | + " ProjectionElem \"_const_9c3f1eec_uri\" AS \"predicate\"\n" + |
| 1628 | + " ProjectionElem \"lot\" AS \"object\"\n" + |
| 1629 | + " ProjectionElemList\n" + |
| 1630 | + " ProjectionElem \"resultnotice\" AS \"subject\"\n" + |
| 1631 | + " ProjectionElem \"_const_6aa9a9c_uri\" AS \"predicate\"\n" + |
| 1632 | + " ProjectionElem \"buyerrole\" AS \"object\"\n" + |
| 1633 | + " ProjectionElemList\n" + |
| 1634 | + " ProjectionElem \"resultnotice\" AS \"subject\"\n" + |
| 1635 | + " ProjectionElem \"_const_183bd06d_uri\" AS \"predicate\"\n" + |
| 1636 | + " ProjectionElem \"proc\" AS \"object\"\n" + |
| 1637 | + " Extension\n" + |
| 1638 | + " Group (countryID, year)\n" + |
| 1639 | + " Join (HashJoinIteration)\n" + |
| 1640 | + " ╠══ Extension [left]\n" + |
| 1641 | + " ║ ├── Join (JoinIterator)\n" + |
| 1642 | + " ║ │ ╠══ StatementPattern (costEstimate=0.71, resultSizeEstimate=0) [left]\n" + |
| 1643 | + " ║ │ ║ s: Var (name=resultnotice)\n" + |
| 1644 | + " ║ │ ║ p: Var (name=_const_183bd06d_uri, value=http://data.europa.eu/a4g/ontology#refersToProcedure, anonymous)\n" |
| 1645 | + + |
| 1646 | + " ║ │ ║ o: Var (name=proc)\n" + |
| 1647 | + " ║ │ ╚══ Join (JoinIterator) [right]\n" + |
| 1648 | + " ║ │ ├── StatementPattern (costEstimate=1.00, resultSizeEstimate=0) [left]\n" + |
| 1649 | + " ║ │ │ s: Var (name=proc)\n" + |
| 1650 | + " ║ │ │ p: Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)\n" |
| 1651 | + + |
| 1652 | + " ║ │ │ o: Var (name=_const_be18ee7b_uri, value=http://data.europa.eu/a4g/ontology#Procedure, anonymous)\n" |
| 1653 | + + |
| 1654 | + " ║ │ └── Join (JoinIterator) [right]\n" + |
| 1655 | + " ║ │ ╠══ StatementPattern (costEstimate=1.00, resultSizeEstimate=0) [left]\n" + |
| 1656 | + " ║ │ ║ s: Var (name=resultnotice)\n" + |
| 1657 | + " ║ │ ║ p: Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)\n" |
| 1658 | + + |
| 1659 | + " ║ │ ║ o: Var (name=_const_77e914ad_uri, value=http://data.europa.eu/a4g/ontology#ResultNotice, anonymous)\n" |
| 1660 | + + |
| 1661 | + " ║ │ ╚══ Join (JoinIterator) [right]\n" + |
| 1662 | + " ║ │ ├── StatementPattern (costEstimate=1.12, resultSizeEstimate=0) [left]\n" + |
| 1663 | + " ║ │ │ s: Var (name=proc)\n" + |
| 1664 | + " ║ │ │ p: Var (name=_const_9c3f1eec_uri, value=http://data.europa.eu/a4g/ontology#hasProcurementScopeDividedIntoLot, anonymous)\n" |
| 1665 | + + |
| 1666 | + " ║ │ │ o: Var (name=lot)\n" + |
| 1667 | + " ║ │ └── Join (JoinIterator) [right]\n" + |
| 1668 | + " ║ │ ╠══ StatementPattern (costEstimate=0.75, resultSizeEstimate=0) [left]\n" |
| 1669 | + + |
| 1670 | + " ║ │ ║ s: Var (name=stat)\n" + |
| 1671 | + " ║ │ ║ p: Var (name=_const_25686184_uri, value=http://data.europa.eu/a4g/ontology#concernsSubmissionsForLot, anonymous)\n" |
| 1672 | + + |
| 1673 | + " ║ │ ║ o: Var (name=lot)\n" + |
| 1674 | + " ║ │ ╚══ Join (JoinIterator) [right]\n" + |
| 1675 | + " ║ │ ├── StatementPattern (costEstimate=1.00, resultSizeEstimate=0) [left]\n" |
| 1676 | + + |
| 1677 | + " ║ │ │ s: Var (name=stat)\n" + |
| 1678 | + " ║ │ │ p: Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)\n" |
| 1679 | + + |
| 1680 | + " ║ │ │ o: Var (name=_const_ea79e75_uri, value=http://data.europa.eu/a4g/ontology#SubmissionStatisticalInformation, anonymous)\n" |
| 1681 | + + |
| 1682 | + " ║ │ └── Join (JoinIterator) [right]\n" + |
| 1683 | + " ║ │ ╠══ Filter [left]\n" + |
| 1684 | + " ║ │ ║ ├── Compare (!=)\n" + |
| 1685 | + " ║ │ ║ │ Var (name=p)\n" + |
| 1686 | + " ║ │ ║ │ ValueConstant (value=http://publications.europa.eu/resource/authority/procurement-procedure-type/neg-wo-call)\n" |
| 1687 | + + |
| 1688 | + " ║ │ ║ └── StatementPattern (costEstimate=2.24, resultSizeEstimate=0)\n" |
| 1689 | + + |
| 1690 | + " ║ │ ║ s: Var (name=proc)\n" + |
| 1691 | + " ║ │ ║ p: Var (name=_const_9c756f6b_uri, value=http://data.europa.eu/a4g/ontology#hasProcedureType, anonymous)\n" |
| 1692 | + + |
| 1693 | + " ║ │ ║ o: Var (name=p)\n" + |
| 1694 | + " ║ │ ╚══ Join (JoinIterator) [right]\n" + |
| 1695 | + " ║ │ ├── StatementPattern (costEstimate=2.24, resultSizeEstimate=0) [left]\n" |
| 1696 | + + |
| 1697 | + " ║ │ │ s: Var (name=stat)\n" + |
| 1698 | + " ║ │ │ p: Var (name=_const_98c73a3c_uri, value=http://data.europa.eu/a4g/ontology#hasReceivedTenders, anonymous)\n" |
| 1699 | + + |
| 1700 | + " ║ │ │ o: Var (name=bidders)\n" + |
| 1701 | + " ║ │ └── Join (JoinIterator) [right]\n" + |
| 1702 | + " ║ │ ╠══ StatementPattern (costEstimate=2.24, resultSizeEstimate=0) [left]\n" |
| 1703 | + + |
| 1704 | + " ║ │ ║ s: Var (name=resultnotice)\n" + |
| 1705 | + " ║ │ ║ p: Var (name=_const_1b0b00ca_uri, value=http://data.europa.eu/a4g/ontology#hasDispatchDate, anonymous)\n" |
| 1706 | + + |
| 1707 | + " ║ │ ║ o: Var (name=ddate)\n" + |
| 1708 | + " ║ │ ╚══ StatementPattern (costEstimate=2.24, resultSizeEstimate=0) [right]\n" |
| 1709 | + + |
| 1710 | + " ║ │ s: Var (name=resultnotice)\n" + |
| 1711 | + " ║ │ p: Var (name=_const_6aa9a9c_uri, value=http://data.europa.eu/a4g/ontology#refersToRole, anonymous)\n" |
| 1712 | + + |
| 1713 | + " ║ │ o: Var (name=buyerrole)\n" + |
| 1714 | + " ║ └── ExtensionElem (year)\n" + |
| 1715 | + " ║ FunctionCall (http://www.w3.org/2005/xpath-functions#year-from-dateTime)\n" + |
| 1716 | + " ║ FunctionCall (http://www.w3.org/2001/XMLSchema#dateTime)\n" + |
| 1717 | + " ║ Var (name=ddate)\n" + |
| 1718 | + " ╚══ Distinct (new scope) [right]\n" + |
| 1719 | + " Projection\n" + |
| 1720 | + " ╠══ ProjectionElemList\n" + |
| 1721 | + " ║ ProjectionElem \"buyerrole\"\n" + |
| 1722 | + " ║ ProjectionElem \"countryID\"\n" + |
| 1723 | + " ╚══ Join (JoinIterator)\n" + |
| 1724 | + " ├── StatementPattern (costEstimate=1.25, resultSizeEstimate=0) [left]\n" + |
| 1725 | + " │ s: Var (name=org)\n" + |
| 1726 | + " │ p: Var (name=_const_beb18915_uri, value=https://www.w3.org/ns/legal#registeredAddress, anonymous)\n" |
| 1727 | + + |
| 1728 | + " │ o: Var (name=orgaddress)\n" + |
| 1729 | + " └── Join (JoinIterator) [right]\n" + |
| 1730 | + " ╠══ StatementPattern (costEstimate=1.12, resultSizeEstimate=0) [left]\n" + |
| 1731 | + " ║ s: Var (name=orgaddress)\n" + |
| 1732 | + " ║ p: Var (name=_const_2f7de0e1_uri, value=http://data.europa.eu/a4g/ontology#hasCountryCode, anonymous)\n" |
| 1733 | + + |
| 1734 | + " ║ o: Var (name=countrycode)\n" + |
| 1735 | + " ╚══ Join (JoinIterator) [right]\n" + |
| 1736 | + " ├── Filter [left]\n" + |
| 1737 | + " │ ╠══ Compare (!=)\n" + |
| 1738 | + " │ ║ Var (name=buytype)\n" + |
| 1739 | + " │ ║ ValueConstant (value=http://publications.europa.eu/resource/authority/buyer-legal-type/eu-int-org)\n" |
| 1740 | + + |
| 1741 | + " │ ╚══ StatementPattern (costEstimate=2.24, resultSizeEstimate=0)\n" + |
| 1742 | + " │ s: Var (name=org)\n" + |
| 1743 | + " │ p: Var (name=_const_1abd8d4b_uri, value=http://data.europa.eu/a4g/ontology#hasBuyerType, anonymous)\n" |
| 1744 | + + |
| 1745 | + " │ o: Var (name=buytype)\n" + |
| 1746 | + " └── Join (JoinIterator) [right]\n" + |
| 1747 | + " ╠══ StatementPattern (costEstimate=2.24, resultSizeEstimate=0) [left]\n" |
| 1748 | + + |
| 1749 | + " ║ s: Var (name=buyerrole)\n" + |
| 1750 | + " ║ p: Var (name=_const_beb855c2_uri, value=http://data.europa.eu/a4g/ontology#playedBy, anonymous)\n" |
| 1751 | + + |
| 1752 | + " ║ o: Var (name=org)\n" + |
| 1753 | + " ╚══ StatementPattern (costEstimate=2.24, resultSizeEstimate=0) [right]\n" |
| 1754 | + + |
| 1755 | + " s: Var (name=countrycode)\n" + |
| 1756 | + " p: Var (name=_const_a825a5f4_uri, value=http://purl.org/dc/elements/1.1/identifier, anonymous)\n" |
| 1757 | + + |
| 1758 | + " o: Var (name=countryID)\n" + |
| 1759 | + " ExtensionElem (_const_f5e5585a_uri)\n" + |
| 1760 | + " ValueConstant (value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type)\n" + |
| 1761 | + " ExtensionElem (_const_be18ee7b_uri)\n" + |
| 1762 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#Procedure)\n" + |
| 1763 | + " ExtensionElem (_const_9c756f6b_uri)\n" + |
| 1764 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#hasProcedureType)\n" + |
| 1765 | + " ExtensionElem (_const_25686184_uri)\n" + |
| 1766 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#concernsSubmissionsForLot)\n" + |
| 1767 | + " ExtensionElem (_const_ea79e75_uri)\n" + |
| 1768 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#SubmissionStatisticalInformation)\n" |
| 1769 | + + |
| 1770 | + " ExtensionElem (_const_98c73a3c_uri)\n" + |
| 1771 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#hasReceivedTenders)\n" + |
| 1772 | + " ExtensionElem (_const_77e914ad_uri)\n" + |
| 1773 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#ResultNotice)\n" + |
| 1774 | + " ExtensionElem (_const_1b0b00ca_uri)\n" + |
| 1775 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#hasDispatchDate)\n" + |
| 1776 | + " ExtensionElem (_const_9c3f1eec_uri)\n" + |
| 1777 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#hasProcurementScopeDividedIntoLot)\n" |
| 1778 | + + |
| 1779 | + " ExtensionElem (_const_6aa9a9c_uri)\n" + |
| 1780 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#refersToRole)\n" + |
| 1781 | + " ExtensionElem (_const_183bd06d_uri)\n" + |
| 1782 | + " ValueConstant (value=http://data.europa.eu/a4g/ontology#refersToProcedure)\n"; |
| 1783 | + SailRepository sailRepository = new SailRepository(new MemoryStore()); |
| 1784 | + addData(sailRepository); |
| 1785 | + |
| 1786 | + try (SailRepositoryConnection connection = sailRepository.getConnection()) { |
| 1787 | + GraphQuery query = connection.prepareGraphQuery(CONSTRUCT); |
| 1788 | + String actual = query.explain(Explanation.Level.Optimized).toString(); |
| 1789 | + |
| 1790 | + assertThat(actual).isEqualToNormalizingNewlines(expected); |
| 1791 | + |
| 1792 | + } |
| 1793 | + sailRepository.shutDown(); |
| 1794 | + |
| 1795 | + } |
| 1796 | + |
1537 | 1797 | @Test |
1538 | 1798 | public void testHaving() { |
1539 | 1799 |
|
|
0 commit comments