(final CompileContext cc)
| 36 | } |
| 37 | |
| 38 | @Override |
| 39 | public Expr optimize(final CompileContext cc) throws QueryException { |
| 40 | exprs[1] = exprs[1].simplifyFor(Simplify.DATA, cc); |
| 41 | |
| 42 | final Expr inputs = exprs[0]; |
| 43 | final long is = inputs.size(); |
| 44 | if(is == 0) return cc.replaceWith(this, inputs); |
| 45 | |
| 46 | // skip optimizations if input may yield items other than maps or arrays |
| 47 | final Type tp = inputs.seqType().type; |
| 48 | final boolean map = tp instanceof MapType, array = tp instanceof ArrayType; |
| 49 | if(!(map || array)) return this; |
| 50 | |
| 51 | final Expr expr = opt(cc); |
| 52 | if(expr != this) return cc.replaceWith(this, expr); |
| 53 | |
| 54 | // derive type from input expression |
| 55 | final Expr keys = exprs[1]; |
| 56 | final SeqType kt = keys.seqType(); |
| 57 | final SeqType st = map ? ((MapType) tp).valueType() : ((ArrayType) tp).valueType(); |
| 58 | Occ occ = st.occ; |
| 59 | if(inputs.size() != 1 || keys == WILDCARD || !kt.one() || kt.mayBeWrapped()) { |
| 60 | // key is wildcard, or expressions yield no single item |
| 61 | occ = occ.union(Occ.ZERO_OR_MORE); |
| 62 | } else if(map) { |
| 63 | // map lookup may result in empty sequence |
| 64 | occ = occ.union(Occ.ZERO); |
| 65 | } |
| 66 | exprType.assign(st.type, occ); |
| 67 | return this; |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * Rewrites the lookup to another expression. |
nothing calls this directly
no test coverage detected