Flattens nested map constructors. @param expr expression to flatten @param list list of expressions @return true if the expression was flattened @throws QueryException query exception
(final Expr expr, final ExprList list)
| 120 | * @throws QueryException query exception |
| 121 | */ |
| 122 | private boolean flatten(final Expr expr, final ExprList list) throws QueryException { |
| 123 | if(expr == Empty.VALUE) { |
| 124 | // ignore empty values |
| 125 | } else if(expr instanceof CMap) { |
| 126 | // { 1: <a/> } |
| 127 | list.add(expr.args()); |
| 128 | } else if(expr instanceof RecordConstructor) { |
| 129 | // { 'a': <a/> } |
| 130 | final RecordType rt = (RecordType) expr.seqType().type; |
| 131 | if(rt.hasOptional()) return false; |
| 132 | final TokenObjectMap<RecordField> fields = rt.fields(); |
| 133 | final int fs = fields.size(); |
| 134 | for(int f = 1; f <= fs; f++) list.add(Str.get(fields.key(f))).add(expr.arg(f - 1)); |
| 135 | } else if(Function._MAP_ENTRY.is(expr)) { |
| 136 | // map:entry('a', 'b') |
| 137 | list.add(expr.arg(0)).add(expr.arg(1)); |
| 138 | } else if(expr instanceof final Value value && value.type instanceof MapType) { |
| 139 | // { 'a': 'b' } |
| 140 | for(final Item item : value) { |
| 141 | ((XQMap) item).forEach((k, v) -> list.add(k).add(v)); |
| 142 | } |
| 143 | } else { |
| 144 | return false; |
| 145 | } |
| 146 | return true; |
| 147 | } |
| 148 | |
| 149 | @Override |
| 150 | public XQMap item(final QueryContext qc, final InputInfo ii) throws QueryException { |