Parses the "FLWORExpr" rule. Parses the "WhereClause" rule. Parses the "WhileClause" rule. Parses the "OrderByClause" rule. Parses the "OrderSpecList" rule. Parses the "GroupByClause" rule. @return query expression or null @throws QueryException query exception
()
| 1151 | * @throws QueryException query exception |
| 1152 | */ |
| 1153 | private Expr flwor() throws QueryException { |
| 1154 | final int s = localVars.openScope(); |
| 1155 | final LinkedList<Clause> clauses = initialClause(null); |
| 1156 | if(clauses == null) return null; |
| 1157 | |
| 1158 | final TokenObjectMap<Var> curr = new TokenObjectMap<>(); |
| 1159 | for(final Clause fl : clauses) |
| 1160 | for(final Var var : fl.vars()) curr.put(var.name.unique(), var); |
| 1161 | |
| 1162 | int size; |
| 1163 | do { |
| 1164 | do { |
| 1165 | size = clauses.size(); |
| 1166 | initialClause(clauses); |
| 1167 | for(final Clause clause : clauses) { |
| 1168 | for(final Var var : clause.vars()) curr.put(var.name.unique(), var); |
| 1169 | } |
| 1170 | } while(size < clauses.size()); |
| 1171 | |
| 1172 | if(wsConsumeWs(WHERE)) { |
| 1173 | alterPos = pos; |
| 1174 | clauses.add(new Where(check(single(), NOWHERE), info())); |
| 1175 | } |
| 1176 | |
| 1177 | if(wsConsumeWs(WHILE)) { |
| 1178 | alterPos = pos; |
| 1179 | clauses.add(new While(check(single(), NOWHILE), info())); |
| 1180 | } |
| 1181 | |
| 1182 | if(wsConsumeWs(GROUP)) { |
| 1183 | wsCheck(BY); |
| 1184 | skipWs(); |
| 1185 | alterPos = pos; |
| 1186 | final GroupSpec[] specs = groupSpecs(clauses); |
| 1187 | |
| 1188 | // find all non-grouping variables that aren't shadowed |
| 1189 | final ArrayList<VarRef> ng = new ArrayList<>(); |
| 1190 | for(final GroupSpec spec : specs) curr.put(spec.var.name.unique(), spec.var); |
| 1191 | VARS: |
| 1192 | for(final Var var : curr.values()) { |
| 1193 | for(final GroupSpec spec : specs) { |
| 1194 | if(spec.var == var) continue VARS; |
| 1195 | } |
| 1196 | ng.add(new VarRef(specs[0].info(), var)); |
| 1197 | } |
| 1198 | |
| 1199 | // add new copies for all non-grouping variables |
| 1200 | final int ns = ng.size(); |
| 1201 | final Var[] ngrp = new Var[ns]; |
| 1202 | for(int i = ns; --i >= 0;) { |
| 1203 | final VarRef ref = ng.get(i); |
| 1204 | // if one groups variables such as $x as xs:integer, then the resulting |
| 1205 | // sequence isn't compatible with the type and can't be assigned |
| 1206 | final Var nv = localVars.add(new Var(ref.var.name, null, qc, ref.var.info)); |
| 1207 | ngrp[i] = nv; |
| 1208 | curr.put(nv.name.unique(), nv); |
| 1209 | } |
| 1210 | clauses.add(new GroupBy(specs, ng.toArray(VarRef[]::new), ngrp, specs[0].info())); |
no test coverage detected