@@ -26,33 +26,27 @@ public Item eval(final Item item1, final Item item2, final InputInfo info)
2626 throws QueryException {
2727 final Type type1 = item1 .type , type2 = item2 .type ;
2828 final boolean num1 = type1 .isNumberOrUntyped (), num2 = type2 .isNumberOrUntyped ();
29- if (num1 ^ num2 ) throw numberError (num1 ? item2 : item1 , info );
30-
31- // numbers or untyped values
32- if (num1 ) {
29+ if (num1 && num2 ) {
3330 return switch (numType (type1 , type2 )) {
3431 case INTEGER -> addInt (item1 , item2 , info );
3532 case DOUBLE -> addDbl (item1 , item2 , info );
3633 case FLOAT -> addFlt (item1 , item2 , info );
3734 default -> addDec (item1 , item2 , info );
3835 };
39- }
40-
41- // dates or durations
42- if (type1 == type2 ) {
43- if (!(item1 instanceof Dur )) throw numberError (item1 , info );
36+ } else if (type1 == type2 ) {
4437 if (type1 == YEAR_MONTH_DURATION ) return new YMDur ((YMDur ) item1 , (YMDur ) item2 , true , info );
4538 if (type1 == DAY_TIME_DURATION ) return new DTDur ((DTDur ) item1 , (DTDur ) item2 , true , info );
39+ } else {
40+ if (type1 .instanceOf (DATE_TIME )) return new Dtm ((Dtm ) item1 , dur (info , item2 ), true , info );
41+ if (type2 .instanceOf (DATE_TIME )) return new Dtm ((Dtm ) item2 , dur (info , item1 ), true , info );
42+ if (type1 == DATE ) return new Dat ((Dat ) item1 , dur (info , item2 ), true , info );
43+ if (type2 == DATE ) return new Dat ((Dat ) item2 , dur (info , item1 ), true , info );
44+ if (type1 == TIME && type2 == DAY_TIME_DURATION )
45+ return new Tim ((Tim ) item1 , (DTDur ) item2 , true );
46+ if (type2 == TIME && type1 == DAY_TIME_DURATION )
47+ return new Tim ((Tim ) item2 , (DTDur ) item1 , true );
4648 }
47- if (type1 .instanceOf (DATE_TIME )) return new Dtm ((Dtm ) item1 , dur (info , item2 ), true , info );
48- if (type2 .instanceOf (DATE_TIME )) return new Dtm ((Dtm ) item2 , dur (info , item1 ), true , info );
49- if (type1 == DATE ) return new Dat ((Dat ) item1 , dur (info , item2 ), true , info );
50- if (type2 == DATE ) return new Dat ((Dat ) item2 , dur (info , item1 ), true , info );
51- if (type1 == TIME && type2 == DAY_TIME_DURATION )
52- return new Tim ((Tim ) item1 , (DTDur ) item2 , true );
53- if (type2 == TIME && type1 == DAY_TIME_DURATION )
54- return new Tim ((Tim ) item2 , (DTDur ) item1 , true );
55- throw typeError (info , type1 , type2 );
49+ throw typeError (info , item1 , item2 );
5650 }
5751
5852 @ Override
@@ -81,8 +75,10 @@ public Expr optimize(final Expr expr1, final Expr expr2, final InputInfo info,
8175
8276 @ Override
8377 public Type type (final Type type1 , final Type type2 ) {
84- if (type1 == YEAR_MONTH_DURATION && type2 == YEAR_MONTH_DURATION ) return YEAR_MONTH_DURATION ;
85- if (type1 == DAY_TIME_DURATION && type2 == DAY_TIME_DURATION ) return DAY_TIME_DURATION ;
78+ if (type1 == type2 ) {
79+ if (type1 == YEAR_MONTH_DURATION ) return YEAR_MONTH_DURATION ;
80+ if (type1 == DAY_TIME_DURATION ) return DAY_TIME_DURATION ;
81+ }
8682 if (type1 .instanceOf (DATE_TIME )) return type1 ;
8783 if (type2 .instanceOf (DATE_TIME )) return type2 ;
8884 if (type1 == DATE || type2 == DATE ) return DATE ;
@@ -104,33 +100,27 @@ public Item eval(final Item item1, final Item item2, final InputInfo info)
104100 throws QueryException {
105101 final Type type1 = item1 .type , type2 = item2 .type ;
106102 final boolean num1 = type1 .isNumberOrUntyped (), num2 = type2 .isNumberOrUntyped ();
107- if (num1 ^ num2 ) throw numberError (num1 ? item2 : item1 , info );
108-
109- // numbers or untyped values
110- if (num1 ) {
103+ if (num1 && num2 ) {
111104 return switch (numType (type1 , type2 )) {
112105 case INTEGER -> subtractInt (item1 , item2 , info );
113106 case DOUBLE -> subtractDbl (item1 , item2 , info );
114107 case FLOAT -> subtractFlt (item1 , item2 , info );
115108 default -> subtractDec (item1 , item2 , info );
116109 };
117- }
118-
119- // dates or durations
120- if (type1 == type2 ) {
121- if (type1 .oneOf (DATE_TIME_STAMP , DATE_TIME , DATE , TIME ))
122- return new DTDur ((ADate ) item1 , (ADate ) item2 , info );
110+ } else if (type1 .instanceOf (DATE_TIME ) && type2 .instanceOf (DATE_TIME )) {
111+ return new DTDur ((ADate ) item1 , (ADate ) item2 , info );
112+ } else if (type1 == type2 ) {
113+ if (type1 .oneOf (DATE , TIME )) return new DTDur ((ADate ) item1 , (ADate ) item2 , info );
114+ if (type1 == DAY_TIME_DURATION ) return new DTDur ((DTDur ) item1 , (DTDur ) item2 , false , info );
123115 if (type1 == YEAR_MONTH_DURATION )
124116 return new YMDur ((YMDur ) item1 , (YMDur ) item2 , false , info );
125- if (type1 == DAY_TIME_DURATION )
126- return new DTDur ((DTDur ) item1 , (DTDur ) item2 , false , info );
127- throw numberError (item1 , info );
117+ } else {
118+ if (type1 .instanceOf (DATE_TIME )) return new Dtm ((Dtm ) item1 , dur (info , item2 ), false , info );
119+ if (type1 == DATE ) return new Dat ((Dat ) item1 , dur (info , item2 ), false , info );
120+ if (type1 == TIME && type2 == DAY_TIME_DURATION )
121+ return new Tim ((Tim ) item1 , (DTDur ) item2 , false );
128122 }
129- if (type1 .instanceOf (DATE_TIME )) return new Dtm ((Dtm ) item1 , dur (info , item2 ), false , info );
130- if (type1 == DATE ) return new Dat ((Dat ) item1 , dur (info , item2 ), false , info );
131- if (type1 == TIME && type2 == DAY_TIME_DURATION )
132- return new Tim ((Tim ) item1 , (DTDur ) item2 , false );
133- throw typeError (info , type1 , type2 );
123+ throw typeError (info , item1 , item2 );
134124 }
135125
136126 @ Override
@@ -161,9 +151,11 @@ public Expr optimize(final Expr expr1, final Expr expr2, final InputInfo info,
161151
162152 @ Override
163153 public Type type (final Type type1 , final Type type2 ) {
164- if (type1 .instanceOf (DATE_TIME ) && type2 .instanceOf (DATE_TIME ) ||
165- type1 == DATE && type2 == DATE ) return DAY_TIME_DURATION ;
166- if (type1 == TIME && type2 == TIME ) return DAY_TIME_DURATION ;
154+ if (type1 .instanceOf (DATE_TIME ) && type2 .instanceOf (DATE_TIME )) return DAY_TIME_DURATION ;
155+ if (type1 == type2 ) {
156+ if (type1 .oneOf (DATE , TIME , DAY_TIME_DURATION )) return DAY_TIME_DURATION ;
157+ if (type1 == YEAR_MONTH_DURATION ) return YEAR_MONTH_DURATION ;
158+ }
167159 if (type1 .instanceOf (DATE_TIME )) return type1 ;
168160 if (type1 == DATE ) return DATE ;
169161 if (type1 == TIME && type2 == DAY_TIME_DURATION ) return TIME ;
@@ -182,35 +174,25 @@ public Calc invert() {
182174 public Item eval (final Item item1 , final Item item2 , final InputInfo info )
183175 throws QueryException {
184176 final Type type1 = item1 .type , type2 = item2 .type ;
185- if (type1 == YEAR_MONTH_DURATION ) {
186- if (item2 instanceof ANum ) return new YMDur ((Dur ) item1 , item2 .dbl (info ), true , info );
187- throw numberError (item2 , info );
188- }
189- if (type2 == YEAR_MONTH_DURATION ) {
190- if (item1 instanceof ANum ) return new YMDur ((Dur ) item2 , item1 .dbl (info ), true , info );
191- throw numberError (item1 , info );
192- }
193- if (type1 == DAY_TIME_DURATION ) {
194- if (item2 instanceof ANum ) return new DTDur ((Dur ) item1 , item2 .dbl (info ), true , info );
195- throw numberError (item2 , info );
196- }
197- if (type2 == DAY_TIME_DURATION ) {
198- if (item1 instanceof ANum ) return new DTDur ((Dur ) item2 , item1 .dbl (info ), true , info );
199- throw numberError (item1 , info );
200- }
201-
202177 final boolean num1 = type1 .isNumberOrUntyped (), num2 = type2 .isNumberOrUntyped ();
203- if (num1 ^ num2 ) throw typeError (info , type1 , type2 );
204- // numbers or untyped values
205- if (num1 ) {
178+ if (type1 == YEAR_MONTH_DURATION ) {
179+ if (num2 ) return new YMDur ((Dur ) item1 , item2 .dbl (info ), true , info );
180+ } else if (type2 == YEAR_MONTH_DURATION ) {
181+ if (num1 ) return new YMDur ((Dur ) item2 , item1 .dbl (info ), true , info );
182+ } else if (type1 == DAY_TIME_DURATION ) {
183+ if (num2 ) return new DTDur ((Dur ) item1 , item2 .dbl (info ), true , info );
184+ } else if (type2 == DAY_TIME_DURATION ) {
185+ if (num1 ) return new DTDur ((Dur ) item2 , item1 .dbl (info ), true , info );
186+ } else if (num1 && num2 ) {
206187 return switch (numType (type1 , type2 )) {
207188 case INTEGER -> multiplyInt (item1 , item2 , info );
208189 case DOUBLE -> multiplyDbl (item1 , item2 , info );
209190 case FLOAT -> multiplyFlt (item1 , item2 , info );
210191 default -> multiplyDec (item1 , item2 , info );
211192 };
212193 }
213- throw numberError (item1 , info );
194+
195+ throw typeError (info , item1 , item2 );
214196 }
215197
216198 @ Override
@@ -263,6 +245,7 @@ public Calc invert() {
263245 public Item eval (final Item item1 , final Item item2 , final InputInfo info )
264246 throws QueryException {
265247 final Type type1 = item1 .type , type2 = item2 .type ;
248+ final boolean num1 = type1 .isNumberOrUntyped (), num2 = type2 .isNumberOrUntyped ();
266249 if (type1 == type2 ) {
267250 if (type1 == YEAR_MONTH_DURATION ) {
268251 final BigDecimal bd = BigDecimal .valueOf (((YMDur ) item2 ).ymd ());
@@ -277,22 +260,18 @@ public Item eval(final Item item1, final Item item2, final InputInfo info)
277260 }
278261 }
279262 if (type1 == YEAR_MONTH_DURATION ) {
280- if (item2 instanceof ANum ) return new YMDur ((Dur ) item1 , item2 .dbl (info ), false , info );
281- throw numberError (item2 , info );
282- }
283- if (type1 == DAY_TIME_DURATION ) {
284- if (item2 instanceof ANum ) return new DTDur ((Dur ) item1 , item2 .dbl (info ), false , info );
285- throw numberError (item2 , info );
263+ if (num2 ) return new YMDur ((Dur ) item1 , item2 .dbl (info ), false , info );
264+ } else if (type1 == DAY_TIME_DURATION ) {
265+ if (num2 ) return new DTDur ((Dur ) item1 , item2 .dbl (info ), false , info );
266+ } else if (num1 && num2 ) {
267+ return switch (numType (type1 , type2 )) {
268+ case DOUBLE -> divideDbl (item1 , item2 , info );
269+ case FLOAT -> divideFlt (item1 , item2 , info );
270+ default -> divideDec (item1 , item2 , info );
271+ };
286272 }
287273
288- // numbers or untyped values
289- if (!type1 .isNumberOrUntyped ()) throw numberError (item1 , info );
290- if (!type2 .isNumberOrUntyped ()) throw numberError (item2 , info );
291- return switch (numType (type1 , type2 )) {
292- case DOUBLE -> divideDbl (item1 , item2 , info );
293- case FLOAT -> divideFlt (item1 , item2 , info );
294- default -> divideDec (item1 , item2 , info );
295- };
274+ throw typeError (info , item1 , item2 );
296275 }
297276
298277 @ Override
@@ -318,8 +297,7 @@ public Expr optimize(final Expr expr1, final Expr expr2, final InputInfo info,
318297
319298 @ Override
320299 public Type type (final Type type1 , final Type type2 ) {
321- if (type1 == YEAR_MONTH_DURATION && type2 == YEAR_MONTH_DURATION ||
322- type1 == DAY_TIME_DURATION && type2 == DAY_TIME_DURATION ) return DECIMAL ;
300+ if (type1 == type2 && type1 .oneOf (YEAR_MONTH_DURATION , DAY_TIME_DURATION )) return DECIMAL ;
323301 if (type1 == YEAR_MONTH_DURATION ) return YEAR_MONTH_DURATION ;
324302 if (type1 == DAY_TIME_DURATION ) return DAY_TIME_DURATION ;
325303 final Type type = numType (type1 , type2 );
@@ -337,17 +315,17 @@ public Calc invert() {
337315 @ Override
338316 public Itr eval (final Item item1 , final Item item2 , final InputInfo info )
339317 throws QueryException {
340-
341- // numbers or untyped values
342318 final Type type1 = item1 .type , type2 = item2 .type ;
343- if (!type1 .isNumberOrUntyped ()) throw numberError (item1 , info );
344- if (!type2 .isNumberOrUntyped ()) throw numberError (item2 , info );
345- return switch (numType (type1 , type2 )) {
346- case INTEGER -> divideIntInt (item1 , item2 , info );
347- case DOUBLE -> divideIntDbl (item1 , item2 , info );
348- case FLOAT -> divideIntFlt (item1 , item2 , info );
349- default -> divideIntDec (item1 , item2 , info );
350- };
319+ final boolean num1 = type1 .isNumberOrUntyped (), num2 = type2 .isNumberOrUntyped ();
320+ if (num1 && num2 ) {
321+ return switch (numType (type1 , type2 )) {
322+ case INTEGER -> divideIntInt (item1 , item2 , info );
323+ case DOUBLE -> divideIntDbl (item1 , item2 , info );
324+ case FLOAT -> divideIntFlt (item1 , item2 , info );
325+ default -> divideIntDec (item1 , item2 , info );
326+ };
327+ }
328+ throw typeError (info , item1 , item2 );
351329 }
352330
353331 @ Override
@@ -383,14 +361,16 @@ public Calc invert() {
383361 public Item eval (final Item item1 , final Item item2 , final InputInfo info )
384362 throws QueryException {
385363 final Type type1 = item1 .type , type2 = item2 .type ;
386- if (!type1 .isNumberOrUntyped ()) throw numberError (item1 , info );
387- if (!type2 .isNumberOrUntyped ()) throw numberError (item2 , info );
388- return switch (numType (type1 , type2 )) {
389- case INTEGER -> moduloInt (item1 , item2 , info );
390- case DOUBLE -> moduloDbl (item1 , item2 , info );
391- case FLOAT -> moduloFlt (item1 , item2 , info );
392- default -> moduloDec (item1 , item2 , info );
393- };
364+ final boolean num1 = type1 .isNumberOrUntyped (), num2 = type2 .isNumberOrUntyped ();
365+ if (num1 && num2 ) {
366+ return switch (numType (type1 , type2 )) {
367+ case INTEGER -> moduloInt (item1 , item2 , info );
368+ case DOUBLE -> moduloDbl (item1 , item2 , info );
369+ case FLOAT -> moduloFlt (item1 , item2 , info );
370+ default -> moduloDec (item1 , item2 , info );
371+ };
372+ }
373+ throw typeError (info , item1 , item2 );
394374 }
395375
396376 @ Override
@@ -489,12 +469,12 @@ public static AtomType numType(final Type type1, final Type type2) {
489469 /**
490470 * Returns a type error.
491471 * @param info input info (can be {@code null})
492- * @param type1 first type
493- * @param type2 second type
472+ * @param item1 first item
473+ * @param item2 second item
494474 * @return query exception
495475 */
496- final QueryException typeError (final InputInfo info , final Type type1 , final Type type2 ) {
497- return CALCTYPE_X_X_X .get (info , info (), type1 , type2 );
476+ final QueryException typeError (final InputInfo info , final Item item1 , final Item item2 ) {
477+ return CALCTYPE_X_X_X_X_X .get (info , item1 . type , item2 . type , item1 , name , item2 );
498478 }
499479
500480 /**
@@ -513,14 +493,6 @@ static Dur dur(final InputInfo info, final Item item) throws QueryException {
513493 throw NODUR_X_X .get (info , type , item );
514494 }
515495
516- /**
517- * Returns a string representation of the operator.
518- * @return string
519- */
520- final String info () {
521- return '\'' + name + "' expression" ;
522- }
523-
524496 @ Override
525497 public String toString () {
526498 return name ;
0 commit comments