Skip to content

Commit 5c3b8c4

Browse files
authored
GH-5174 backport of GH-5153 (#5176)
2 parents 442a573 + fb8b7fb commit 5c3b8c4

2 files changed

Lines changed: 51 additions & 11 deletions

File tree

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/QueryEvaluationUtil.java

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.eclipse.rdf4j.model.Value;
2121
import org.eclipse.rdf4j.model.base.CoreDatatype;
2222
import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
23+
import org.eclipse.rdf4j.model.impl.BooleanLiteral;
2324
import org.eclipse.rdf4j.model.util.Literals;
2425
import org.eclipse.rdf4j.query.algebra.Compare.CompareOp;
2526
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
@@ -62,13 +63,20 @@ public class QueryEvaluationUtil {
6263
* @throws ValueExprEvaluationException In case the application of the EBV algorithm results in a type error.
6364
*/
6465
public static boolean getEffectiveBooleanValue(Value value) throws ValueExprEvaluationException {
66+
67+
if (value == BooleanLiteral.TRUE) {
68+
return true;
69+
} else if (value == BooleanLiteral.FALSE) {
70+
return false;
71+
}
72+
6573
if (value.isLiteral()) {
6674
Literal literal = (Literal) value;
6775
String label = literal.getLabel();
6876
CoreDatatype.XSD datatype = literal.getCoreDatatype().asXSDDatatype().orElse(null);
6977

7078
if (datatype == CoreDatatype.XSD.STRING) {
71-
return label.length() > 0;
79+
return !label.isEmpty();
7280
} else if (datatype == CoreDatatype.XSD.BOOLEAN) {
7381
// also false for illegal values
7482
return "true".equals(label) || "1".equals(label);
@@ -107,6 +115,15 @@ public static boolean compare(Value leftVal, Value rightVal, CompareOp operator)
107115

108116
public static boolean compare(Value leftVal, Value rightVal, CompareOp operator, boolean strict)
109117
throws ValueExprEvaluationException {
118+
if (leftVal == rightVal) {
119+
switch (operator) {
120+
case EQ:
121+
return true;
122+
case NE:
123+
return false;
124+
}
125+
}
126+
110127
if (leftVal != null && leftVal.isLiteral() && rightVal != null && rightVal.isLiteral()) {
111128
// Both left and right argument is a Literal
112129
return compareLiterals((Literal) leftVal, (Literal) rightVal, operator, strict);
@@ -162,6 +179,15 @@ public static boolean compareLiterals(Literal leftLit, Literal rightLit, Compare
162179
// - CoreDatatype.XSD:string
163180
// - RDF term (equal and unequal only)
164181

182+
if (leftLit == rightLit) {
183+
switch (operator) {
184+
case EQ:
185+
return true;
186+
case NE:
187+
return false;
188+
}
189+
}
190+
165191
CoreDatatype.XSD leftCoreDatatype = leftLit.getCoreDatatype().asXSDDatatype().orElse(null);
166192
CoreDatatype.XSD rightCoreDatatype = rightLit.getCoreDatatype().asXSDDatatype().orElse(null);
167193

@@ -329,7 +355,7 @@ && isSupportedDatatype(rightCoreDatatype)) {
329355
* <a href="http://www.w3.org/TR/rdf-concepts/#section-blank-nodes">6.6 Blank Nodes of [CONCEPTS]</a>.
330356
* </ul>
331357
* </blockquote>
332-
*
358+
* <p>
333359
* (emphasis ours)
334360
* <p>
335361
* When applying the SPARQL specification in a minimally-conforming manner, RDFterm-equal is supposed to return a
@@ -349,7 +375,6 @@ && isSupportedDatatype(rightCoreDatatype)) {
349375
* @param rightCoreDatatype the right datatype to compare
350376
* @throws ValueExprEvaluationException if query evaluation is operating in strict mode, and the two supplied
351377
* datatypes are both supported datatypes but not comparable.
352-
*
353378
* @see <a href="https://github.com/eclipse/rdf4j/issues/3947">Github issue #3947</a>
354379
*/
355380
private static void validateDatatypeCompatibility(boolean strict, CoreDatatype.XSD leftCoreDatatype,
@@ -432,13 +457,13 @@ private static boolean compareWithOperator(CompareOp operator, int i) {
432457
*/
433458
public static boolean isPlainLiteral(Value v) {
434459
if (v.isLiteral()) {
435-
return isPlainLiteral(((Literal) v));
460+
return isPlainLiteral((Literal) v);
436461
}
437462
return false;
438463
}
439464

440465
public static boolean isPlainLiteral(Literal l) {
441-
assert l.getLanguage().isEmpty() || (l.getCoreDatatype() == CoreDatatype.RDF.LANGSTRING);
466+
assert l.getLanguage().isEmpty() || l.getCoreDatatype() == CoreDatatype.RDF.LANGSTRING;
442467
return l.getCoreDatatype() == CoreDatatype.XSD.STRING || l.getCoreDatatype() == CoreDatatype.RDF.LANGSTRING;
443468
}
444469

@@ -510,10 +535,10 @@ public static boolean compatibleArguments(Literal arg1, Literal arg2) {
510535
// 3. The first argument is a language literal and the second
511536
// argument is a literal typed as CoreDatatype.XSD:string
512537

513-
return (isSimpleLiteral(arg1) && isSimpleLiteral(arg2))
514-
|| (Literals.isLanguageLiteral(arg1) && Literals.isLanguageLiteral(arg2)
515-
&& arg1.getLanguage().equals(arg2.getLanguage()))
516-
|| (Literals.isLanguageLiteral(arg1) && isSimpleLiteral(arg2));
538+
return isSimpleLiteral(arg1) && isSimpleLiteral(arg2)
539+
|| Literals.isLanguageLiteral(arg1) && Literals.isLanguageLiteral(arg2)
540+
&& arg1.getLanguage().equals(arg2.getLanguage())
541+
|| Literals.isLanguageLiteral(arg1) && isSimpleLiteral(arg2);
517542
}
518543

519544
/**

core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/MaxCountConstraintComponent.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,20 @@
4747
import org.eclipse.rdf4j.sail.shacl.ast.planNodes.ValidationTuple;
4848
import org.eclipse.rdf4j.sail.shacl.ast.targets.EffectiveTarget;
4949
import org.eclipse.rdf4j.sail.shacl.wrapper.data.ConnectionsGroup;
50+
import org.slf4j.Logger;
51+
import org.slf4j.LoggerFactory;
5052

5153
public class MaxCountConstraintComponent extends AbstractConstraintComponent {
5254

55+
private static final Logger logger = LoggerFactory.getLogger(MaxCountConstraintComponent.class);
56+
57+
// Performance degrades quickly as the maxCount increases when using a SPARQL Validation Approach. The default is 5,
58+
// but it can be tuned using the system property below.
59+
private static final String SPARQL_VALIDATION_APPROACH_LIMIT_PROPERTY = "org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.MaxCountConstraintComponent.sparqlValidationApproachLimit";
60+
public static long SPARQL_VALIDATION_APPROACH_LIMIT = System
61+
.getProperty(SPARQL_VALIDATION_APPROACH_LIMIT_PROPERTY) == null ? 1
62+
: Long.parseLong(System.getProperty(SPARQL_VALIDATION_APPROACH_LIMIT_PROPERTY));
63+
5364
private final long maxCount;
5465

5566
public MaxCountConstraintComponent(long maxCount) {
@@ -235,8 +246,12 @@ public ValidationQuery generateSparqlValidationQuery(ConnectionsGroup connection
235246

236247
@Override
237248
public ValidationApproach getOptimalBulkValidationApproach() {
238-
// performance of large maxCount is terrible
239-
if (maxCount > 5) {
249+
if (maxCount > SPARQL_VALIDATION_APPROACH_LIMIT) {
250+
if (logger.isDebugEnabled()) {
251+
logger.debug(
252+
"maxCount is {}, which is greater than the limit of {}, using ValidationApproach.Transactional instead of ValidationApproach.SPARQL for {}",
253+
maxCount, SPARQL_VALIDATION_APPROACH_LIMIT, stringRepresentationOfValue(getId()));
254+
}
240255
return ValidationApproach.Transactional;
241256
}
242257
return ValidationApproach.SPARQL;

0 commit comments

Comments
 (0)