Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion basex-core/src/main/java/org/basex/core/jobs/QueryJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.basex.query.*;
import org.basex.query.value.*;
import org.basex.query.value.item.*;
import org.basex.query.value.type.*;
import org.basex.util.*;
import org.basex.util.log.*;

Expand Down Expand Up @@ -124,7 +125,7 @@ public static Item toTime(final String string, final InputInfo info) throws Quer
// time
if(ADate.TIME.matcher(string).matches()) return new Tim(token(string), info);
// dateTime
return new Dtm(token(string), info);
return new Dtm(token(string), AtomType.DATE_TIME, info);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion basex-core/src/main/java/org/basex/query/QueryDateTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.*;

import org.basex.query.value.item.*;
import org.basex.query.value.type.*;
import org.basex.util.*;

/**
Expand Down Expand Up @@ -37,7 +38,7 @@ public QueryDateTime() throws QueryException {
final String znm = zon.substring(0, 3), zns = zon.substring(3);
time = new Tim(token(hms + znm + ':' + zns), null);
date = new Dat(token(ymd + znm + ':' + zns), null);
datm = new Dtm(token(ymd + 'T' + hms + znm + ':' + zns), null);
datm = new Dtm(token(ymd + 'T' + hms + znm + ':' + zns), AtomType.DATE_TIME_STAMP, null);
zone = new DTDur(Strings.toInt(znm), Strings.toInt(zns));
nano = System.nanoTime();
}
Expand Down
2 changes: 2 additions & 0 deletions basex-core/src/main/java/org/basex/query/QueryError.java
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,8 @@ public enum QueryError {
/** Error code. */
INVALIDZONE_X(FORG, 1, "Invalid timezone: %."),
/** Error code. */
MISSINGZONE_X(FORG, 1, "xs:dateTimeStamp value must have a timezone: %."),
/** Error code. */
FUNCCAST_X_X(FORG, 1, "Cannot convert to %: %."),
/** Error code. */
FUNCCAST_X_X_X(FORG, 1, "Cannot convert % to %: %."),
Expand Down
15 changes: 8 additions & 7 deletions basex-core/src/main/java/org/basex/query/expr/Calc.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public Item eval(final Item item1, final Item item2, final InputInfo info)
if(type1 == YEAR_MONTH_DURATION) return new YMDur((YMDur) item1, (YMDur) item2, true, info);
if(type1 == DAY_TIME_DURATION) return new DTDur((DTDur) item1, (DTDur) item2, true, info);
}
if(type1 == DATE_TIME) return new Dtm((Dtm) item1, dur(info, item2), true, info);
if(type2 == DATE_TIME) return new Dtm((Dtm) item2, dur(info, item1), true, info);
if(type1.instanceOf(DATE_TIME)) return new Dtm((Dtm) item1, dur(info, item2), true, info);
if(type2.instanceOf(DATE_TIME)) return new Dtm((Dtm) item2, dur(info, item1), true, info);
if(type1 == DATE) return new Dat((Dat) item1, dur(info, item2), true, info);
if(type2 == DATE) return new Dat((Dat) item2, dur(info, item1), true, info);
if(type1 == TIME && type2 == DAY_TIME_DURATION)
Expand Down Expand Up @@ -83,7 +83,8 @@ public Expr optimize(final Expr expr1, final Expr expr2, final InputInfo info,
public Type type(final Type type1, final Type type2) {
if(type1 == YEAR_MONTH_DURATION && type2 == YEAR_MONTH_DURATION) return YEAR_MONTH_DURATION;
if(type1 == DAY_TIME_DURATION && type2 == DAY_TIME_DURATION) return DAY_TIME_DURATION;
if(type1 == DATE_TIME || type2 == DATE_TIME) return DATE_TIME;
if(type1.instanceOf(DATE_TIME)) return type1;
if(type2.instanceOf(DATE_TIME)) return type2;
if(type1 == DATE || type2 == DATE) return DATE;
if(type1 == TIME && type2 == DAY_TIME_DURATION ||
type1 == DAY_TIME_DURATION && type2 == TIME) return TIME;
Expand Down Expand Up @@ -117,15 +118,15 @@ public Item eval(final Item item1, final Item item2, final InputInfo info)

// dates or durations
if(type1 == type2) {
if(type1 == DATE_TIME || type1 == DATE || type1 == TIME)
if(type1.oneOf(DATE_TIME_STAMP, DATE_TIME, DATE, TIME))
return new DTDur((ADate) item1, (ADate) item2, info);
if(type1 == YEAR_MONTH_DURATION)
return new YMDur((YMDur) item1, (YMDur) item2, false, info);
if(type1 == DAY_TIME_DURATION)
return new DTDur((DTDur) item1, (DTDur) item2, false, info);
throw numberError(item1, info);
}
if(type1 == DATE_TIME) return new Dtm((Dtm) item1, dur(info, item2), false, info);
if(type1.instanceOf(DATE_TIME)) return new Dtm((Dtm) item1, dur(info, item2), false, info);
if(type1 == DATE) return new Dat((Dat) item1, dur(info, item2), false, info);
if(type1 == TIME && type2 == DAY_TIME_DURATION)
return new Tim((Tim) item1, (DTDur) item2, false);
Expand Down Expand Up @@ -160,10 +161,10 @@ public Expr optimize(final Expr expr1, final Expr expr2, final InputInfo info,

@Override
public Type type(final Type type1, final Type type2) {
if(type1 == DATE_TIME && type2 == DATE_TIME ||
if(type1.instanceOf(DATE_TIME) && type2.instanceOf(DATE_TIME) ||
type1 == DATE && type2 == DATE) return DAY_TIME_DURATION;
if(type1 == TIME && type2 == TIME) return DAY_TIME_DURATION;
if(type1 == DATE_TIME) return DATE_TIME;
if(type1.instanceOf(DATE_TIME)) return type1;
if(type1 == DATE) return DATE;
if(type1 == TIME && type2 == DAY_TIME_DURATION) return TIME;
return numType(type1, type2);
Expand Down
1 change: 1 addition & 0 deletions basex-core/src/main/java/org/basex/query/expr/CmpG.java
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ public static boolean comparable(final Type type1, final Type type2, final boole
type1.isNumber() && type2.isNumber() ||
type1.isStringOrUntyped() && type2.isStringOrUntyped() ||
untyped && (type1.isUntyped() || type2.isUntyped()) ||
type1.instanceOf(AtomType.DATE_TIME) && type2.instanceOf(AtomType.DATE_TIME) ||
type1.instanceOf(AtomType.DURATION) && type2.instanceOf(AtomType.DURATION) ||
type1.instanceOf(AtomType.BINARY) && type2.instanceOf(AtomType.BINARY);
}
Expand Down
8 changes: 4 additions & 4 deletions basex-core/src/main/java/org/basex/query/func/Function.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public enum Function implements AFunction {
params(), DATE_O, flag(NDT)),
/** XQuery function. */
CURRENT_DATETIME(FnCurrentDateTime::new, "current-dateTime()",
params(), DATE_TIME_O, flag(NDT)),
params(), DATE_TIME_STAMP_O, flag(NDT)),
/** XQuery function. */
CURRENT_TIME(FnCurrentTime::new, "current-time()",
params(), TIME_O, flag(NDT)),
Expand Down Expand Up @@ -721,7 +721,7 @@ ITEM_ZM, flag(HOF)),
params(ITEM_ZM), STRING_O),
/** XQuery function. */
UNIX_DATETIME(FnUnixDateTime::new, "unix-dateTime([value])",
params(INTEGER_ZO), DATE_TIME_O),
params(INTEGER_ZO), DATE_TIME_STAMP_O),
/** XQuery function. */
UNORDERED(FnUnordered::new, "unordered(input)",
params(ITEM_ZM), ITEM_ZM),
Expand Down Expand Up @@ -1196,7 +1196,7 @@ ANY_URI_O, flag(NDT), CLIENT_URI, Perm.CREATE),
params(INTEGER_O, INTEGER_O), STRING_O, CONVERT_URI),
/** XQuery function. */
_CONVERT_INTEGER_TO_DATETIME(ConvertIntegerToDateTime::new, "integer-to-dateTime(value)",
params(INTEGER_O), DATE_TIME_O, CONVERT_URI),
params(INTEGER_O), DATE_TIME_STAMP_O, CONVERT_URI),
/** XQuery function. */
_CONVERT_INTEGER_TO_DAYTIME(ConvertIntegerToDayTime::new, "integer-to-dayTime(value)",
params(INTEGER_O), DAY_TIME_DURATION_O, CONVERT_URI),
Expand Down Expand Up @@ -1456,7 +1456,7 @@ ANY_URI_O, flag(NDT), CLIENT_URI, Perm.CREATE),
params(STRING_O), BOOLEAN_O, flag(NDT), FILE_URI, Perm.ADMIN),
/** XQuery function. */
_FILE_LAST_MODIFIED(FileLastModified::new, "last-modified(path)",
params(STRING_O), DATE_TIME_O, flag(NDT), FILE_URI, Perm.ADMIN),
params(STRING_O), DATE_TIME_STAMP_O, flag(NDT), FILE_URI, Perm.ADMIN),
/** XQuery function. */
_FILE_LINE_SEPARATOR(FileLineSeparator::new, "line-separator()",
params(), STRING_O, FILE_URI),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.basex.query.value.array.*;
import org.basex.query.value.item.*;
import org.basex.query.value.node.*;
import org.basex.query.value.type.*;
import org.basex.util.*;

/**
Expand Down Expand Up @@ -194,7 +195,7 @@ final long timestamp(final Item header, final QueryContext qc) throws QueryExcep
if(header instanceof final ANode node) {
final byte[] value = node.attribute(Q_LAST_MODIFIED);
try {
if(value != null) return toMs(new Dtm(value, info), qc);
if(value != null) return toMs(new Dtm(value, AtomType.DATE_TIME, info), qc);
} catch(final QueryException ex) {
Util.debug(ex);
throw ARCHIVE_TIMESTAMP_X.get(info, value);
Expand Down
7 changes: 5 additions & 2 deletions basex-core/src/main/java/org/basex/query/func/fn/FnMin.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ final Item minmax(final boolean min, final QueryContext qc) throws QueryExceptio
final Type type = item.type;
if(!type.isSortable()) throw COMPARE_X_X.get(info, type, item);

final boolean string = item instanceof AStr, numeric = !string && !(
final boolean string = item instanceof AStr;
final boolean numeric = !string && !(
type == BOOLEAN || item instanceof ADate || item instanceof Dur || item instanceof Bin);
final boolean dateTime = type.instanceOf(DATE_TIME);
if(numeric) {
if(type.isUntyped()) item = DOUBLE.cast(item, qc, info);
if(item == Dbl.NAN || item == Flt.NAN) return item;
Expand All @@ -68,7 +70,8 @@ final Item minmax(final boolean min, final QueryContext qc) throws QueryExceptio
if(type2.isUntyped()) it = DOUBLE.cast(it, qc, info);
if(it == Dbl.NAN || it == Flt.NAN) return it;
}
if(!(numeric ? it instanceof ANum : string ? it instanceof AStr : type == type2)) {
if(!(numeric ? it instanceof ANum : string ? it instanceof AStr : dateTime ?
type2.instanceOf(DATE_TIME) : type == type2)) {
throw ARGTYPE_X_X_X.get(info, type, type2, it);
}
if(min ^ item.compare(it, collation, true, info) < 0) item = it;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.basex.query.func.*;
import org.basex.query.value.item.*;
import org.basex.query.value.seq.*;
import org.basex.query.value.type.*;
import org.basex.util.*;

/**
Expand Down Expand Up @@ -107,7 +108,7 @@ private Dtm parse() throws QueryException {
addNumber(tb, Math.abs(z % 60), 2);
}
try {
return new Dtm(tb.finish(), info);
return new Dtm(tb.finish(), AtomType.DATE_TIME, info);
} catch(final QueryException ex) {
Util.debug(ex);
throw QueryError.IETF_INV_X.get(info, original);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,10 @@ public final byte[] formatDate(final ADate dt, final byte[] languageTag, final b
case 'w':
num = date.toJava().toGregorianCalendar().get(Calendar.WEEK_OF_MONTH);
// first week of month: fix value, according to ISO 8601
if(num == 0) num = new Dtm(new Dtm(date), new DTDur(date.day() * 24, 0),
false, info).toJava().toGregorianCalendar().get(Calendar.WEEK_OF_MONTH);
if(num == 0) {
num = new Dtm(new Dtm(date, AtomType.DATE_TIME, info), new DTDur(date.day() * 24, 0),
false, info).toJava().toGregorianCalendar().get(Calendar.WEEK_OF_MONTH);
}
err = tim;
break;
case 'H':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,15 @@ public final boolean equal(final Item item, final Collation coll, final InputInf

@Override
public final boolean deepEqual(final Item item, final DeepEqual deep) throws QueryException {
return type == item.type && compare(item, deep.info) == 0 &&
(!deep.options.get(DeepEqualOptions.TIMEZONES) || tz == ((ADate) item).tz);
return (type.instanceOf(item.type) || item.type.instanceOf(type))
&& compare(item, deep.info) == 0
&& (!deep.options.get(DeepEqualOptions.TIMEZONES) || tz == ((ADate) item).tz);
}

@Override
public final boolean atomicEqual(final Item item) throws QueryException {
return this == item || type == item.type && compare(item, null) == 0 &&
hasTz() == ((ADate) item).hasTz();
return this == item || (type.instanceOf(item.type) || item.type.instanceOf(type))
&& compare(item, null) == 0 && hasTz() == ((ADate) item).hasTz();
}

@Override
Expand Down
26 changes: 18 additions & 8 deletions basex-core/src/main/java/org/basex/query/value/item/Dtm.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.basex.util.*;

/**
* DateTime item ({@code xs:dateTime}).
* DateTime item ({@code xs:dateTime} and {@code xs:dateTimeStamp}).
*
* @author BaseX Team, BSD License
* @author Christian Gruen
Expand All @@ -23,9 +23,13 @@ public final class Dtm extends ADate {
/**
* Constructor.
* @param date date
* @param type item type
* @param info input info (can be {@code null})
* @throws QueryException query exception
*/
public Dtm(final ADate date) {
super(AtomType.DATE_TIME, date);
public Dtm(final ADate date, final Type type, final InputInfo info) throws QueryException {
super(type, date);
if(type == AtomType.DATE_TIME_STAMP && !hasTz()) throw MISSINGZONE_X.get(info, date);
if(hour == -1) {
hour = 0;
minute = 0;
Expand Down Expand Up @@ -56,11 +60,12 @@ public Dtm(final Dat date, final Tim time, final InputInfo info) throws QueryExc
/**
* Constructor.
* @param dateTime date time
* @param type item type
* @param info input info (can be {@code null})
* @throws QueryException query exception
*/
public Dtm(final byte[] dateTime, final InputInfo info) throws QueryException {
super(AtomType.DATE_TIME);
public Dtm(final byte[] dateTime, final Type type, final InputInfo info) throws QueryException {
super(type);
final int i = Token.indexOf(dateTime, 'T');
if(i == -1) throw dateError(dateTime, XDTM, info);
date(Token.substring(dateTime, 0, i), XDTM, info);
Expand All @@ -78,7 +83,7 @@ public Dtm(final byte[] dateTime, final InputInfo info) throws QueryException {
public Dtm(final Dtm dateTime, final Dur dur, final boolean plus, final InputInfo info)
throws QueryException {

this(dateTime);
this(dateTime, dateTime.type, info);
if(dur instanceof final DTDur dtd) {
calc(dtd, plus);
if(year <= MIN_YEAR || year > MAX_YEAR) throw YEARRANGE_X.get(info, year);
Expand All @@ -90,7 +95,7 @@ public Dtm(final Dtm dateTime, final Dur dur, final boolean plus, final InputInf
@Override
public Dtm timeZone(final DTDur dur, final boolean undefined, final InputInfo info)
throws QueryException {
final Dtm dtm = new Dtm(this);
final Dtm dtm = new Dtm(this, AtomType.DATE_TIME, info);
dtm.tz(dur, undefined, info);
return dtm;
}
Expand All @@ -102,9 +107,14 @@ public Dtm timeZone(final DTDur dur, final boolean undefined, final InputInfo in
*/
public static Dtm get(final long ms) {
try {
return new Dtm(Token.token(DateTime.format(new Date(ms))), null);
return new Dtm(Token.token(DateTime.format(new Date(ms))), AtomType.DATE_TIME_STAMP, null);
} catch(final QueryException ex) {
throw Util.notExpected(ex);
}
}

@Override
public boolean comparable(final Item item) {
return item instanceof Dtm;
}
}
Loading