Tries to rewrite fn:string-length. @param op operator @param cc compilation context @return optimized or original expression @throws QueryException query exception
(final CmpOp op, final CompileContext cc)
| 314 | * @throws QueryException query exception |
| 315 | */ |
| 316 | private Expr optStringLength(final CmpOp op, final CompileContext cc) throws QueryException { |
| 317 | final Expr expr1 = exprs[0], expr2 = exprs[1]; |
| 318 | if(!(STRING_LENGTH.is(expr1) && expr2 instanceof final ANum num)) return this; |
| 319 | |
| 320 | final Expr[] args = expr1.args(); |
| 321 | final long[] counts = countRange(op, num.dbl()); |
| 322 | if(counts == COUNT_TRUE || counts == COUNT_FALSE) { |
| 323 | // string-length(A) >= 0 → true() |
| 324 | final Expr arg1 = args.length > 0 ? args[0] : cc.qc.focus.value; |
| 325 | if(arg1 != null) { |
| 326 | final SeqType st1 = arg1.seqType(); |
| 327 | if(st1.zero() || st1.one() && !st1.mayBeWrapped()) { |
| 328 | return Bln.get(counts == COUNT_TRUE); |
| 329 | } |
| 330 | } |
| 331 | } |
| 332 | if(counts == COUNT_EMPTY || counts == COUNT_EXISTS) { |
| 333 | // string-length(A) > 0 → boolean(string(A)) |
| 334 | final Function func = counts == COUNT_EMPTY ? NOT : BOOLEAN; |
| 335 | return cc.function(func, info, cc.function(STRING, info, args)); |
| 336 | } |
| 337 | return this; |
| 338 | } |
| 339 | |
| 340 | /** |
| 341 | * Tries to rewrite comparisons with empty strings. |