Skip to content

Commit 43b124e

Browse files
Merge branch 'main' of github.com:BaseXdb/basex
2 parents 448f79f + f01732f commit 43b124e

File tree

11 files changed

+31
-21
lines changed

11 files changed

+31
-21
lines changed

basex-core/src/main/java/org/basex/query/expr/gflwor/GFLWOR.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,12 +1038,12 @@ public Expr copy(final CompileContext cc, final IntObjectMap<Var> vm) {
10381038
}
10391039

10401040
/**
1041-
* Checks if this FLWOR expression has only 'for', 'let', 'where', and 'while' clauses.
1041+
* Checks if this FLWOR expression has only 'for', 'let', and 'where' clauses.
10421042
* @return result of check
10431043
*/
10441044
private boolean isFLW() {
10451045
return ((Checks<Clause>) clause -> clause instanceof For || clause instanceof Let ||
1046-
clause instanceof Where || clause instanceof While).all(clauses);
1046+
clause instanceof Where).all(clauses);
10471047
}
10481048

10491049
@Override

basex-core/src/main/java/org/basex/query/func/fn/FnBuildDateTime.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,10 @@ private static DTDur getDuration(final XQMap map, final Str key) throws QueryExc
175175
* Checks the year component for validity.
176176
* @param year the year to check
177177
* @param info input info for error reporting
178-
* @throws QueryException if the year is out of range or zero
178+
* @throws QueryException if the year is out of range
179179
*/
180180
private static void checkYear(final long year, final InputInfo info) throws QueryException {
181-
if(year <= ADate.MIN_YEAR || year > ADate.MAX_YEAR || year == 0)
181+
if(year <= ADate.MIN_YEAR || year > ADate.MAX_YEAR)
182182
throw INVDATETIMEVALUE_X_X.get(info, YEAR, year);
183183
}
184184

@@ -233,7 +233,7 @@ private static void checkDate(final long year, final long month, final long day,
233233
checkYear(year, info);
234234
checkMonth(month, info);
235235
checkDayOnly(day, info);
236-
final int dom = ADate.daysOfMonth(year < 0 ? year + 1 : year, (int) month - 1);
236+
final int dom = ADate.daysOfMonth(year, (int) month - 1);
237237
if(day > dom) throw INVDATETIMEVALUE_X_X.get(info, DAY, day);
238238
}
239239

basex-core/src/main/java/org/basex/query/value/item/ADate.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public abstract class ADate extends ADateDur {
3232
/** Pattern for two digits. */
3333
static final String DD = "(\\d{2})";
3434
/** Year pattern. */
35-
static final String YEAR = "(-?(000[1-9]|00[1-9]\\d|0[1-9]\\d{2}|[1-9]\\d{3,}))";
35+
static final String YEAR = "(-?([1-9]\\d{3,}|0\\d{3}))";
3636
/** Date pattern. */
3737
static final String ZONE = "(([-+])" + DD + ':' + DD + "|Z)?";
3838
/** Day per months. */
@@ -47,7 +47,7 @@ public abstract class ADate extends ADateDur {
4747
/** Year.
4848
* <ul>
4949
* <li> 1 - {@code Long#MAX_VALUE}-1: AD</li>
50-
* <li> 0 - {@link Long#MIN_VALUE}: BC, +1 added</li>
50+
* <li> 0 - {@link Long#MIN_VALUE}: BC</li>
5151
* <li> {@link Long#MAX_VALUE}: undefined</li>
5252
* </ul> */
5353
long year = Long.MAX_VALUE;
@@ -110,8 +110,6 @@ final void date(final byte[] date, final String exp, final InputInfo info) throw
110110
final Matcher mt = DATE.matcher(Token.string(date).trim());
111111
if(!mt.matches()) throw dateError(date, exp, info);
112112
year = toLong(mt.group(1), false, info);
113-
// +1 is added to BC values to simplify computations
114-
if(year < 0) year++;
115113
month = (byte) (Strings.toInt(mt.group(3)) - 1);
116114
day = (byte) (Strings.toInt(mt.group(4)) - 1);
117115

@@ -282,7 +280,7 @@ protected void tz(final DTDur dur, final boolean undefined, final InputInfo info
282280

283281
@Override
284282
public final long yea() {
285-
return year > 0 ? year : year - 1;
283+
return year;
286284
}
287285

288286
@Override
@@ -339,7 +337,7 @@ public byte[] string(final InputInfo ii) {
339337
final TokenBuilder tb = new TokenBuilder();
340338
final boolean ymd = year != Long.MAX_VALUE;
341339
if(ymd) {
342-
if(year <= 0) tb.add('-');
340+
if(year < 0) tb.add('-');
343341
prefix(tb, Math.abs(yea()), 4);
344342
tb.add('-');
345343
prefix(tb, mon(), 2);
@@ -427,7 +425,7 @@ private int compare(final Item item, final InputInfo info) throws QueryException
427425
@Override
428426
public final XMLGregorianCalendar toJava() {
429427
return DF.newXMLGregorianCalendar(
430-
year == Long.MAX_VALUE ? null : BigInteger.valueOf(year > 0 ? year : year - 1),
428+
year == Long.MAX_VALUE ? null : BigInteger.valueOf(year),
431429
month >= 0 ? month + 1 : Integer.MIN_VALUE,
432430
day >= 0 ? day + 1 : Integer.MIN_VALUE,
433431
hour >= 0 ? hour : Integer.MIN_VALUE,

basex-core/src/main/java/org/basex/query/value/item/Dbl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public static double parse(final byte[] value, final InputInfo info) throws Quer
156156

157157
final byte[] v = Token.trim(value);
158158
if(Token.eq(v, Token.NAN)) return Double.NaN;
159-
if(Token.eq(v, Token.POSITIVE_INF)) return Double.POSITIVE_INFINITY;
159+
if(Token.eq(v, Token.POSITIVE_INF, Token.POSITIVE_INF_PLUS)) return Double.POSITIVE_INFINITY;
160160
if(Token.eq(v, Token.NEGATIVE_INF)) return Double.NEGATIVE_INFINITY;
161161
throw BasicType.DOUBLE.castError(value, info);
162162
}

basex-core/src/main/java/org/basex/query/value/item/Dtm.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public boolean comparable(final Item item) {
140140
*
141141
* <p>Components must be supplied in their lexical representation:
142142
* month 1–12, day 1–31, hours 0–23, minutes 0–59, seconds in [0–60).
143-
* For BC years, pass a negative year (not 0). Undefined components must
143+
* For BC years, pass a negative year or 0 (for year 0). Undefined components must
144144
* be {@code null}.</p>
145145
*
146146
* <p>This method is intended as a low-level construction helper for
@@ -164,7 +164,7 @@ public static ADate buildUnchecked(final BasicType targetType,
164164
final Long hours, final Long minutes, final BigDecimal seconds,
165165
final DTDur zone, final InputInfo info) throws QueryException {
166166
final Dtm base = new Dtm(targetType);
167-
base.year = year == null ? Long.MAX_VALUE : year < 0 ? year + 1 : year;
167+
base.year = year == null ? Long.MAX_VALUE : year;
168168
base.month = month == null ? -1 : (byte) (month - 1);
169169
base.day = day == null ? -1 : (byte) (day - 1);
170170
base.hour = hours == null ? -1 : hours.byteValue();

basex-core/src/main/java/org/basex/query/value/item/Flt.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public boolean equals(final Object obj) {
141141
public static float parse(final byte[] value, final InputInfo info) throws QueryException {
142142
final byte[] v = Token.trim(value);
143143
if(Token.eq(v, Token.NAN)) return Float.NaN;
144-
if(Token.eq(v, Token.POSITIVE_INF)) return Float.POSITIVE_INFINITY;
144+
if(Token.eq(v, Token.POSITIVE_INF, Token.POSITIVE_INF_PLUS)) return Float.POSITIVE_INFINITY;
145145
if(Token.eq(v, Token.NEGATIVE_INF)) return Float.NEGATIVE_INFINITY;
146146
if(!Token.eq(v, Token.POSITIVE_INFINITY, Token.NEGATIVE_INFINITY)) {
147147
try {

basex-core/src/main/java/org/basex/query/value/item/GDt.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ public GDt(final byte[] date, final Type type, final InputInfo info) throws Quer
6565

6666
if(i < 2) {
6767
year = toLong(mt.group(1), false, info);
68-
// +1 is added to BC values to simplify computations
69-
if(year < 0) year++;
7068
if(year < MIN_YEAR || year >= MAX_YEAR) throw DATERANGE_X_X.get(info, type, date);
7169
}
7270
if(i > 0 && i < 4) {
@@ -105,7 +103,7 @@ public byte[] string(final InputInfo ii) {
105103
if(year == Long.MAX_VALUE) {
106104
tb.add('-');
107105
} else {
108-
if(year <= 0) tb.add('-');
106+
if(year < 0) tb.add('-');
109107
prefix(tb, Math.abs(yea()), 4);
110108
}
111109
if(month >= 0 || day >= 0) tb.add('-');

basex-core/src/main/java/org/basex/util/Token.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public final class Token {
4646
public static final byte[] NAN = token("NaN");
4747
/** Token 'INF'. */
4848
public static final byte[] POSITIVE_INF = token("INF");
49+
/** Token '+INF'. */
50+
public static final byte[] POSITIVE_INF_PLUS = token("+INF");
4951
/** Token '-INF'. */
5052
public static final byte[] NEGATIVE_INF = token("-INF");
5153
/** Token 'Infinity'. */

basex-core/src/test/java/org/basex/query/expr/GFLWORTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,4 +523,14 @@ public final class GFLWORTest extends SandboxTest {
523523
"1\n2", exists(Pipeline.class));
524524
check("let $a := <a/>[text()] while $a return $a", "", root(IterFilter.class));
525525
}
526+
527+
/** Do not flatten nested FLWOR expressions with while clauses. */
528+
@Test public void gh2634() {
529+
query("for $max in (1 to 10) return (for $a in 0 to $max while $a < 1 return $a)",
530+
"0\n0\n0\n0\n0\n0\n0\n0\n0\n0");
531+
query("for $x in (1, 2) return (for $a in (1, 2, 3) while $a < 3 return $a)",
532+
"1\n2\n1\n2");
533+
query("for $x in (1, 2) for $y in (for $a in (1, 2, 3) while $a < 3 return $a) return ($x, $y)",
534+
"1\n1\n1\n2\n2\n1\n2\n2");
535+
}
526536
}

basex-core/src/test/java/org/basex/query/func/FnModuleTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,8 @@ public final class FnModuleTest extends SandboxTest {
415415
+ " \"timezone\": xs:dayTimeDuration('PT1H') }"),
416416
"---03+01:00");
417417
query(func.args(" dateTime-record(day:=4)"), "---04");
418+
// year 0
419+
query(func.args(" {\"year\": 0, \"month\": 1, \"day\": 1}"), "0000-01-01");
418420

419421
// empty map
420422
error(func.args(" {}"), INVDATETIMEFIELDS_X);
@@ -427,8 +429,6 @@ public final class FnModuleTest extends SandboxTest {
427429
// out of range component (minutes)
428430
error(func.args(" {\"hours\": 14, \"minutes\": 60, \"seconds\": 0,"
429431
+ " \"timezone\": xs:dayTimeDuration('PT1H') }"), INVDATETIMEVALUE_X_X);
430-
// invalid year (0)
431-
error(func.args(" {\"year\": 0}"), INVDATETIMEVALUE_X_X);
432432
// invalid date (March 0)
433433
error(func.args(" {\"year\": 2026, \"month\": 3, \"day\": 0,"
434434
+ " \"timezone\": xs:dayTimeDuration('PT1H') }"), INVDATETIMEVALUE_X_X);

0 commit comments

Comments
 (0)