Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
hmottestad committed Apr 30, 2023
1 parent 6486d07 commit 41c60de
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public interface Resource extends Value {

// Empty place holder as common supertype of IRI and BNode

default Type getValueType(){
if(isIRI()) return Type.IRI;
if(isBNode()) return Type.BNODE;
return Type.TRIPLE;
}

@Override
default boolean isResource() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ public enum Type {
TRIPLE
}

Type getValueType();
default Type getValueType(){
if(isIRI()) return Type.IRI;
if(isLiteral()) return Type.LITERAL;
if(isBNode()) return Type.BNODE;
return Type.TRIPLE;
}

/**
* Check if the object is an instance of the given type. Typically 2x than using instanceof.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ public class OrderComparator implements Comparator<BindingSet> {

private final static Logger logger = LoggerFactory.getLogger(OrderComparator.class);

private final ValueComparator cmp;
private final Comparator<Value> cmp;

private final Comparator<BindingSet> bindingContentsComparator;

public OrderComparator(EvaluationStrategy strategy, Order order, ValueComparator cmp,
public OrderComparator(EvaluationStrategy strategy, Order order, Comparator<Value> cmp,
QueryEvaluationContext context) {
this.cmp = cmp;
this.bindingContentsComparator = precompileComparator(strategy, order, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation.util;

import static javax.xml.datatype.DatatypeConstants.FIELD_UNDEFINED;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;

import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;

import org.eclipse.rdf4j.common.annotation.InternalUseOnly;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Value;
Expand All @@ -29,6 +18,16 @@
import org.eclipse.rdf4j.model.util.Literals;
import org.eclipse.rdf4j.query.algebra.Compare.CompareOp;

import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;

import static javax.xml.datatype.DatatypeConstants.FIELD_UNDEFINED;

/**
* This class will take over for QueryEvaluationUtil. Currently marked as InternalUseOnly because there may still be
* changes to how this class works.
Expand Down Expand Up @@ -107,12 +106,12 @@ public static Result compare(Value leftVal, Value rightVal, CompareOp operator,
} else {
// All other value combinations
switch (operator) {
case EQ:
return Result.fromBoolean(Objects.equals(leftVal, rightVal));
case NE:
return Result.fromBoolean(!Objects.equals(leftVal, rightVal));
default:
return Result.incompatibleValueExpression;
case EQ:
return Result.fromBoolean(Objects.equals(leftVal, rightVal));
case NE:
return Result.fromBoolean(!Objects.equals(leftVal, rightVal));
default:
return Result.incompatibleValueExpression;
}
}
}
Expand All @@ -125,7 +124,7 @@ public static Result compare(Value leftVal, Value rightVal, CompareOp operator,
* @param rightLit the right literal argument of the comparison.
* @param operator the comparison operator to use.
* @return {@code true} if execution of the supplied operator on the supplied arguments succeeds, {@code false}
* otherwise.
* otherwise.
*/
public static Result compareLiterals(Literal leftLit, Literal rightLit, CompareOp operator) {
return compareLiterals(leftLit, rightLit, operator, true);
Expand All @@ -149,7 +148,7 @@ public static Order compareLiterals(Literal leftLit, Literal rightLit, boolean s
if (leftCoreDatatype == CoreDatatype.XSD.STRING && rightCoreDatatype == CoreDatatype.XSD.STRING) {
return Order.from(leftLit.getLabel().compareTo(rightLit.getLabel()));
} else if (leftCoreDatatype != null
&& rightCoreDatatype != null) {
&& rightCoreDatatype != null) {

if (leftCoreDatatype.isXSDDatatype() && rightCoreDatatype.isXSDDatatype()) {

Expand All @@ -159,8 +158,8 @@ public static Order compareLiterals(Literal leftLit, Literal rightLit, boolean s

try {
Order order = handleCommonDatatype(leftLit, rightLit, strict, leftCoreDatatype,
rightCoreDatatype,
commonDatatype);
rightCoreDatatype,
commonDatatype);

if (order == Order.illegalArgument) {
if (leftLit.equals(rightLit)) {
Expand Down Expand Up @@ -188,8 +187,8 @@ public static Order compareLiterals(Literal leftLit, Literal rightLit, boolean s
// operator

return otherCases(leftLit, rightLit, leftCoreDatatype,
rightCoreDatatype, leftCoreDatatype == null && leftLit.getCoreDatatype() == CoreDatatype.RDF.LANGSTRING,
rightCoreDatatype == null && rightLit.getCoreDatatype() == CoreDatatype.RDF.LANGSTRING);
rightCoreDatatype, leftCoreDatatype == null && leftLit.getCoreDatatype() == CoreDatatype.RDF.LANGSTRING,
rightCoreDatatype == null && rightLit.getCoreDatatype() == CoreDatatype.RDF.LANGSTRING);

}

Expand All @@ -202,7 +201,7 @@ public static Order compareLiterals(Literal leftLit, Literal rightLit, boolean s
* @param strict boolean indicating whether comparison should use strict (minimally-conforming) SPARQL 1.1
* operator behavior, or extended behavior.
* @return {@code true} if execution of the supplied operator on the supplied arguments succeeds, {@code false}
* otherwise.
* otherwise.
*/
public static Result compareLiterals(Literal leftLit, Literal rightLit, CompareOp operator, boolean strict) {
Order order = compareLiterals(leftLit, rightLit, strict);
Expand Down Expand Up @@ -241,16 +240,16 @@ public static Instant xmlGregorianCalendarToInstant(XMLGregorianCalendar xmlGreg
}

int nanosecond = xmlGregCal.getFractionalSecond() != null
? xmlGregCal.getFractionalSecond().movePointRight(9).intValue()
: 0;
? xmlGregCal.getFractionalSecond().movePointRight(9).intValue()
: 0;
if (nanosecond < 0) {
return null;
}

LocalDateTime localDateTime = LocalDateTime.of(year, month, day, hour, minute, second, nanosecond);
ZoneOffset zoneOffset = xmlGregCal.getTimezone() == FIELD_UNDEFINED
? ZoneOffset.UTC
: ZoneOffset.ofTotalSeconds(xmlGregCal.getTimezone() * 60);
? ZoneOffset.UTC
: ZoneOffset.ofTotalSeconds(xmlGregCal.getTimezone() * 60);
return localDateTime.toInstant(zoneOffset);
}

Expand All @@ -277,12 +276,12 @@ public static Instant xmlGregorianCalendarDateToInstant(XMLGregorianCalendar xml

LocalDateTime localDateTime = LocalDateTime.of(year, month, day, 0, 0, 0, 0);
ZoneOffset zoneOffset = xmlGregCal.getTimezone() == FIELD_UNDEFINED
? ZoneOffset.UTC
: ZoneOffset.ofTotalSeconds(xmlGregCal.getTimezone() * 60);
? ZoneOffset.UTC
: ZoneOffset.ofTotalSeconds(xmlGregCal.getTimezone() * 60);
return localDateTime.toInstant(zoneOffset);
}

private final static int[] daysInMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private final static int[] daysInMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

public static Instant yearMonthDayToInstant(int year, int month, int day) {

Expand Down Expand Up @@ -310,8 +309,8 @@ public static Instant yearMonthDayToInstant(int year, int month, int day) {
public static long toEpoch(int year, int month, int day, int hour, int minute, int second) {

long dateEpoch = ((long) day + (long) (year - ((14 - month) / 12)) + ((long) (year - ((14 - month) / 12))) / 4
- ((long) (year - ((14 - month) / 12))) / 100 + ((long) (year - ((14 - month) / 12))) / 400
+ (31 * ((long) (month + (12 * ((14 - month) / 12) - 2)))) / 12) - 719529;
- ((long) (year - ((14 - month) / 12))) / 100 + ((long) (year - ((14 - month) / 12))) / 400
+ (31 * ((long) (month + (12 * ((14 - month) / 12) - 2)))) / 12) - 719529;

//
// // Calculate the number of days from 1970 to the given year
Expand All @@ -338,8 +337,8 @@ public static long toEpoch(int year, int month, int day, int hour, int minute, i
}

private static Order handleCommonDatatype(Literal leftLit, Literal rightLit, boolean strict,
CoreDatatype.XSD leftCoreDatatype, CoreDatatype.XSD rightCoreDatatype,
CoreDatatype.XSD commonDatatype) {
CoreDatatype.XSD leftCoreDatatype, CoreDatatype.XSD rightCoreDatatype,
CoreDatatype.XSD commonDatatype) {
if (commonDatatype == CoreDatatype.XSD.DOUBLE) {
return Order.from(Double.compare(leftLit.doubleValue(), rightLit.doubleValue()));
} else if (commonDatatype == CoreDatatype.XSD.FLOAT) {
Expand Down Expand Up @@ -371,7 +370,7 @@ private static Order handleCommonDatatype(Literal leftLit, Literal rightLit, boo
XMLGregorianCalendar left = leftLit.calendarValue();
XMLGregorianCalendar right = rightLit.calendarValue();

int compare = compareXMLGregorianCalendar(leftCoreDatatype, rightCoreDatatype, left, right);
int compare = compareXMLGregorianCalendar(leftCoreDatatype, rightCoreDatatype, left, right, leftLit, rightLit);

// Note: XMLGregorianCalendar.compare() returns compatible values (-1, 0, 1) but INDETERMINATE
// needs special treatment
Expand Down Expand Up @@ -403,41 +402,48 @@ private static Order handleCommonDatatype(Literal leftLit, Literal rightLit, boo
}

private static int compareXMLGregorianCalendar(CoreDatatype.XSD leftCoreDatatype,
CoreDatatype.XSD rightCoreDatatype, XMLGregorianCalendar left, XMLGregorianCalendar right) {
CoreDatatype.XSD rightCoreDatatype, XMLGregorianCalendar left, XMLGregorianCalendar right, Literal leftLit, Literal rightLit) {
if (leftCoreDatatype == rightCoreDatatype && left.getTimezone() == right.getTimezone()) {
int leftYear = left.getYear();
int rightYear = right.getYear();
if (leftYear > 1971 && rightYear > 1971 && leftYear < 2038 && rightYear < 2038) {

int compare = Long.compare(
toEpoch(leftYear, left.getMonth(), left.getDay(), left.getHour(), left.getMinute(),
left.getSecond()),
toEpoch(rightYear, right.getMonth(), right.getDay(), right.getHour(), right.getMinute(),
right.getSecond())
toEpoch(leftYear, left.getMonth(), left.getDay(), left.getHour(), left.getMinute(),
left.getSecond()),
toEpoch(rightYear, right.getMonth(), right.getDay(), right.getHour(), right.getMinute(),
right.getSecond())
);
if (compare != 0) {
// since the values are different we can assume that we don't need to account for a higher precision
return compare;
} else {
// since the values are equal we need to account for a higher precision
return left.compare(right);
if (leftLit.getLabel().equals(rightLit.getLabel())) {
return 0;
} else {
return left.compare(right);
}
}
} else {
// since the values are equal we need to account for a higher precision
return left.compare(right);
}
if (leftLit.getLabel().equals(rightLit.getLabel())) {
return 0;
} else {
return left.compare(right);
} }
} else {
return left.compare(right);
}
}

private static Order otherCases(Literal leftLit, Literal rightLit, CoreDatatype leftCoreDatatype,
CoreDatatype rightCoreDatatype, boolean leftLangLit, boolean rightLangLit) {
CoreDatatype rightCoreDatatype, boolean leftLangLit, boolean rightLangLit) {
boolean literalsEqual = leftLit.equals(rightLit);

if (!literalsEqual) {
if (!leftLangLit && !rightLangLit && isSupportedDatatype(leftCoreDatatype)
&& isSupportedDatatype(rightCoreDatatype)) {
&& isSupportedDatatype(rightCoreDatatype)) {
// left and right arguments have incompatible but supported datatypes

// we need to check that the lexical-to-value mapping for both datatypes succeeds
Expand Down Expand Up @@ -482,7 +488,7 @@ && isSupportedDatatype(rightCoreDatatype)) {
}

private static CoreDatatype.XSD getCommonDatatype(boolean strict, CoreDatatype.XSD leftCoreDatatype,
CoreDatatype.XSD rightCoreDatatype) {
CoreDatatype.XSD rightCoreDatatype) {
if (leftCoreDatatype == null || rightCoreDatatype == null) {
return null;
}
Expand All @@ -507,7 +513,7 @@ private static CoreDatatype.XSD getCommonDatatype(boolean strict, CoreDatatype.X
}

private static CoreDatatype.XSD getCommonNumericDatatype(CoreDatatype.XSD leftCoreDatatype,
CoreDatatype.XSD rightCoreDatatype) {
CoreDatatype.XSD rightCoreDatatype) {
if (leftCoreDatatype == CoreDatatype.XSD.DOUBLE || rightCoreDatatype == CoreDatatype.XSD.DOUBLE) {
return CoreDatatype.XSD.DOUBLE;
}
Expand All @@ -525,7 +531,7 @@ private static CoreDatatype.XSD getCommonNumericDatatype(CoreDatatype.XSD leftCo
* optionally a language tag.
*
* @see <a href="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/#dfn-plain-literal">RDF Literal
* Documentation</a>
* Documentation</a>
*/
public static boolean isPlainLiteral(Value v) {
if (v.isLiteral()) {
Expand Down Expand Up @@ -599,7 +605,7 @@ public static boolean isStringLiteral(Value v) {
* @param arg2 the second argument
* @return true iff the two supplied arguments are argument compatible, false otherwise
* @see <a href="http://www.w3.org/TR/sparql11-query/#func-arg-compatibility">SPARQL Argument Compatibility
* Rules</a>
* Rules</a>
*/
public static boolean compatibleArguments(Literal arg1, Literal arg2) {
// 1. The arguments are literals typed as CoreDatatype.XSD:string
Expand All @@ -608,9 +614,9 @@ public static boolean compatibleArguments(Literal arg1, Literal arg2) {
// argument is a literal typed as CoreDatatype.XSD:string

return (isSimpleLiteral(arg1) && isSimpleLiteral(arg2))
|| (Literals.isLanguageLiteral(arg1) && Literals.isLanguageLiteral(arg2)
&& arg1.getLanguage().equals(arg2.getLanguage()))
|| (Literals.isLanguageLiteral(arg1) && isSimpleLiteral(arg2));
|| (Literals.isLanguageLiteral(arg1) && Literals.isLanguageLiteral(arg2)
&& arg1.getLanguage().equals(arg2.getLanguage()))
|| (Literals.isLanguageLiteral(arg1) && isSimpleLiteral(arg2));
}

/**
Expand All @@ -625,8 +631,8 @@ public static boolean isStringLiteral(Literal l) {

private static boolean isSupportedDatatype(CoreDatatype datatype) {
return datatype != null && datatype.isXSDDatatype()
&& (datatype == CoreDatatype.XSD.STRING || ((CoreDatatype.XSD) datatype).isNumericDatatype()
|| ((CoreDatatype.XSD) datatype).isCalendarDatatype());
&& (datatype == CoreDatatype.XSD.STRING || ((CoreDatatype.XSD) datatype).isNumericDatatype()
|| ((CoreDatatype.XSD) datatype).isCalendarDatatype());
}

public enum Result {
Expand Down Expand Up @@ -712,35 +718,35 @@ public Result toResult(CompareOp operator) {

if (this == notEqual) {
switch (operator) {
case EQ:
return Result._false;
case NE:
return Result._true;
case EQ:
return Result._false;
case NE:
return Result._true;
case LT:
case LE:
case GE:
case GT:
return Result.incompatibleValueExpression;
default:
return Result.illegalArgument;
}
}

switch (operator) {
case LT:
return Result.fromBoolean(value < 0);
case LE:
return Result.fromBoolean(value <= 0);
case EQ:
return Result.fromBoolean(value == 0);
case NE:
return Result.fromBoolean(value != 0);
case GE:
return Result.fromBoolean(value >= 0);
case GT:
return Result.incompatibleValueExpression;
return Result.fromBoolean(value > 0);
default:
return Result.illegalArgument;
}
}

switch (operator) {
case LT:
return Result.fromBoolean(value < 0);
case LE:
return Result.fromBoolean(value <= 0);
case EQ:
return Result.fromBoolean(value == 0);
case NE:
return Result.fromBoolean(value != 0);
case GE:
return Result.fromBoolean(value >= 0);
case GT:
return Result.fromBoolean(value > 0);
default:
return Result.illegalArgument;
}
}
}
Expand Down
Loading

0 comments on commit 41c60de

Please sign in to comment.