|
1 | 1 | /******************************************************************************* |
2 | | - * Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others. |
| 2 | + * Copyright (c) 2025 Eclipse RDF4J contributors. |
3 | 3 | * |
4 | 4 | * All rights reserved. This program and the accompanying materials |
5 | 5 | * are made available under the terms of the Eclipse Distribution License v1.0 |
|
43 | 43 | import org.eclipse.rdf4j.model.util.Values; |
44 | 44 | import org.eclipse.rdf4j.query.BindingSet; |
45 | 45 | import org.eclipse.rdf4j.query.MalformedQueryException; |
| 46 | +import org.eclipse.rdf4j.query.QueryLanguage; |
46 | 47 | import org.eclipse.rdf4j.query.algebra.AggregateFunctionCall; |
47 | 48 | import org.eclipse.rdf4j.query.algebra.ArbitraryLengthPath; |
48 | 49 | import org.eclipse.rdf4j.query.algebra.DeleteData; |
|
70 | 71 | import org.eclipse.rdf4j.query.parser.ParsedQuery; |
71 | 72 | import org.eclipse.rdf4j.query.parser.ParsedTupleQuery; |
72 | 73 | import org.eclipse.rdf4j.query.parser.ParsedUpdate; |
| 74 | +import org.eclipse.rdf4j.query.parser.QueryParserUtil; |
| 75 | +import org.eclipse.rdf4j.query.parser.sparql.SPARQLParser; |
73 | 76 | import org.eclipse.rdf4j.query.parser.sparql.aggregate.AggregateCollector; |
74 | 77 | import org.eclipse.rdf4j.query.parser.sparql.aggregate.AggregateFunction; |
75 | 78 | import org.eclipse.rdf4j.query.parser.sparql.aggregate.AggregateFunctionFactory; |
@@ -1002,6 +1005,158 @@ public void testApostropheInsertData() { |
1002 | 1005 | parser.parseUpdate(query, null); |
1003 | 1006 | } |
1004 | 1007 |
|
| 1008 | + @Test |
| 1009 | + public void testInvalidConstructQueryWithPropertyPathInConstructClause() { |
| 1010 | + String invalidSparqlQuery = " CONSTRUCT {\n" + |
| 1011 | + " ?s (!a)* ?p .\n" + |
| 1012 | + " }\n" + |
| 1013 | + " WHERE {\n" + |
| 1014 | + " ?s (!a)* ?p .\n" + |
| 1015 | + " }"; |
| 1016 | + |
| 1017 | + assertThrows(MalformedQueryException.class, () -> { |
| 1018 | + parser.parseQuery(invalidSparqlQuery, null); |
| 1019 | + }); |
| 1020 | + |
| 1021 | + } |
| 1022 | + |
| 1023 | + @Test |
| 1024 | + public void testValidConstructQueryWithPropertyPathInWhereClause() { |
| 1025 | + String validSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + |
| 1026 | + "CONSTRUCT {\n" + |
| 1027 | + " ?person foaf:knows ?friend .\n" + |
| 1028 | + "}\n" + |
| 1029 | + "WHERE {\n" + |
| 1030 | + " ?person foaf:knows+ ?friend .\n" + |
| 1031 | + "}"; |
| 1032 | + |
| 1033 | + ParsedQuery parsedQuery = parser.parseQuery(validSparqlQuery, null); |
| 1034 | + assertThat(parsedQuery.getSourceString()).isEqualTo(validSparqlQuery); |
| 1035 | + |
| 1036 | + } |
| 1037 | + |
| 1038 | + @Test |
| 1039 | + public void testValidConstructQueryWithBlankNodeAsSubject() { |
| 1040 | + String validSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" |
| 1041 | + + "PREFIX site: <http://example.org/stats#>\n" |
| 1042 | + + "\n" |
| 1043 | + + "CONSTRUCT { [] foaf:name ?name }\n" |
| 1044 | + + "WHERE\n" |
| 1045 | + + "{ [] foaf:name ?name ;\n" |
| 1046 | + + " site:hits ?hits .\n" |
| 1047 | + + "}\n" |
| 1048 | + + "ORDER BY desc(?hits)\n" |
| 1049 | + + "LIMIT 2"; |
| 1050 | + |
| 1051 | + ParsedQuery parsedQuery = parser.parseQuery(validSparqlQuery, null); |
| 1052 | + assertThat(parsedQuery.getSourceString()).isEqualTo(validSparqlQuery); |
| 1053 | + |
| 1054 | + } |
| 1055 | + |
| 1056 | + @Test |
| 1057 | + public void testInvalidConstructQueryWithPropertyPathInPredicatePosition() { |
| 1058 | + String invalidSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + |
| 1059 | + "CONSTRUCT {\n" + |
| 1060 | + " ?person foaf:knows+ ?friend . " + |
| 1061 | + "}\n" + |
| 1062 | + "WHERE {\n" + |
| 1063 | + " ?person foaf:knows+ ?friend .\n" + |
| 1064 | + "}"; |
| 1065 | + assertThrows(MalformedQueryException.class, () -> { |
| 1066 | + parser.parseQuery(invalidSparqlQuery, null); |
| 1067 | + }); |
| 1068 | + |
| 1069 | + } |
| 1070 | + |
| 1071 | + @Test |
| 1072 | + public void testInvalidConstructQueryWithPropertyPathAlternationInPredicate() { |
| 1073 | + String invalidSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + |
| 1074 | + "CONSTRUCT {\n" + |
| 1075 | + " ?x (foaf:knows|foaf:friendOf) ?y . " + |
| 1076 | + "}\n" + |
| 1077 | + "WHERE {\n" + |
| 1078 | + " ?x (foaf:knows|foaf:friendOf) ?y .\n" + |
| 1079 | + "} "; |
| 1080 | + assertThrows(MalformedQueryException.class, () -> { |
| 1081 | + parser.parseQuery(invalidSparqlQuery, null); |
| 1082 | + }); |
| 1083 | + |
| 1084 | + } |
| 1085 | + |
| 1086 | + @Test |
| 1087 | + public void testInvalidConstructQueryWithPathSequenceInPredicate() { |
| 1088 | + String invalidSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + |
| 1089 | + "CONSTRUCT {\n" + |
| 1090 | + " ?a foaf:knows/foaf:knows ?c . " + |
| 1091 | + "}\n" + |
| 1092 | + "WHERE {\n" + |
| 1093 | + " ?a foaf:knows/foaf:knows ?c . .\n" + |
| 1094 | + "} "; |
| 1095 | + assertThrows(MalformedQueryException.class, () -> { |
| 1096 | + parser.parseQuery(invalidSparqlQuery, null); |
| 1097 | + }); |
| 1098 | + |
| 1099 | + } |
| 1100 | + |
| 1101 | + @Test |
| 1102 | + public void testInvalidConstructQueryWithNegatedPropertySet() { |
| 1103 | + String invalidSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + |
| 1104 | + "CONSTRUCT {\n" + |
| 1105 | + " ?s !foaf:knows ?o . " + |
| 1106 | + "}\n" + |
| 1107 | + "WHERE {\n" + |
| 1108 | + " ?s !foaf:knows ?o .\n" + |
| 1109 | + "} "; |
| 1110 | + assertThrows(MalformedQueryException.class, () -> { |
| 1111 | + parser.parseQuery(invalidSparqlQuery, null); |
| 1112 | + }); |
| 1113 | + |
| 1114 | + } |
| 1115 | + |
| 1116 | + @Test |
| 1117 | + public void testInvalidConstructQueryWithZeroOrMorePathInPredicate() { |
| 1118 | + String invalidSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + |
| 1119 | + "CONSTRUCT {\n" + |
| 1120 | + " ?s foaf:knows* ?o . " + |
| 1121 | + "}\n" + |
| 1122 | + "WHERE {\n" + |
| 1123 | + " ?s foaf:knows* ?o .\n" + |
| 1124 | + "} "; |
| 1125 | + assertThrows(MalformedQueryException.class, () -> { |
| 1126 | + parser.parseQuery(invalidSparqlQuery, null); |
| 1127 | + }); |
| 1128 | + } |
| 1129 | + |
| 1130 | + @Test |
| 1131 | + public void testInvalidConstructQueryWithZeroOrMorePathInPredicates() { |
| 1132 | + String invalidSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + |
| 1133 | + "CONSTRUCT {\n" + |
| 1134 | + " ?s foaf:knows ?o . " + |
| 1135 | + " ?s foaf:name+ ?o . " + |
| 1136 | + "}\n" + |
| 1137 | + "WHERE {\n" + |
| 1138 | + " ?s foaf:knows* ?o .\n" + |
| 1139 | + " ?s foaf:name ?o .\n" + |
| 1140 | + "} "; |
| 1141 | + assertThrows(MalformedQueryException.class, () -> { |
| 1142 | + parser.parseQuery(invalidSparqlQuery, null); |
| 1143 | + }); |
| 1144 | + } |
| 1145 | + |
| 1146 | + @Test |
| 1147 | + public void testInvalidConstructQueryWithMalformedTriple() { |
| 1148 | + String invalidSparqlQuery = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + |
| 1149 | + "CONSTRUCT {\n" + |
| 1150 | + " ?person foaf:name \n" + |
| 1151 | + "}\n" + |
| 1152 | + "WHERE {\n" + |
| 1153 | + " ?person foaf:name ?name .\n" + |
| 1154 | + "} "; |
| 1155 | + assertThrows(MalformedQueryException.class, () -> { |
| 1156 | + parser.parseQuery(invalidSparqlQuery, null); |
| 1157 | + }); |
| 1158 | + } |
| 1159 | + |
1005 | 1160 | private AggregateFunctionFactory buildDummyFactory() { |
1006 | 1161 | return new AggregateFunctionFactory() { |
1007 | 1162 | @Override |
|
0 commit comments