2727public final class Range extends Arr {
2828 /** Dummy value for representing the last item in a sequence. */
2929 private static final long LAST = 1L << 52 ;
30- /** Expressions yield integers. */
31- boolean ints ;
3230
3331 /**
3432 * Constructor.
@@ -48,16 +46,36 @@ public Expr optimize(final CompileContext cc) throws QueryException {
4846 if (values (false , cc )) return cc .preEval (this );
4947
5048 final Expr min = exprs [0 ], max = exprs [1 ];
51- final SeqType st1 = min .seqType (), st2 = max .seqType ();
52- ints = st1 .instanceOf (Types .INTEGER_O ) && st2 .instanceOf (Types .INTEGER_O );
53- if (min .equals (max )) {
54- exprType .assign (Occ .EXACTLY_ONE );
55- if (ints && !min .has (Flag .NDT )) expr = min ;
49+ if (!min .has (Flag .NDT )) {
50+ if (min .equals (max )) {
51+ // identical operands: $int to $int
52+ exprType .assign (Occ .EXACTLY_ONE );
53+ if (integers ()) expr = min ;
54+ } else if (max instanceof Arith arith && min .equals (max .arg (0 ))) {
55+ if (arith .calc .oneOf (Calc .ADD , Calc .SUBTRACT ) && arith .arg (1 ) instanceof Itr itr ) {
56+ // known result size: . to . + 10
57+ final long n = (arith .calc == Calc .ADD ? itr .itr () : -itr .itr ()) + 1 ;
58+ if (n < 1 ) {
59+ expr = Empty .VALUE ;
60+ } else {
61+ exprType .assign (seqType (), n );
62+ }
63+ }
64+ }
5665 }
5766 }
5867 return cc .replaceWith (this , expr );
5968 }
6069
70+ /**
71+ * Indicates if the range operands are known to return single integers.
72+ * @return result of check
73+ */
74+ boolean integers () {
75+ final SeqType st1 = exprs [0 ].seqType (), st2 = exprs [1 ].seqType ();
76+ return st1 .instanceOf (Types .INTEGER_O ) && st2 .instanceOf (Types .INTEGER_O );
77+ }
78+
6179 @ Override
6280 public Value value (final QueryContext qc ) throws QueryException {
6381 final Item min = exprs [0 ].atomItem (qc , info );
@@ -75,9 +93,7 @@ public Value value(final QueryContext qc) throws QueryException {
7593
7694 @ Override
7795 public Range copy (final CompileContext cc , final IntObjectMap <Var > vm ) {
78- final Range r = copyType (new Range (info , copyAll (cc , vm , exprs )));
79- r .ints = ints ;
80- return r ;
96+ return copyType (new Range (info , copyAll (cc , vm , exprs )));
8197 }
8298
8399 @ Override
0 commit comments