Parse a record selection expression.
| 1317 | |
| 1318 | // Parse a record selection expression. |
| 1319 | RseNode* PAR_rse(thread_db* tdbb, CompilerScratch* csb, SSHORT rse_op) |
| 1320 | { |
| 1321 | SET_TDBB(tdbb); |
| 1322 | |
| 1323 | const ULONG blrOffset = csb->csb_blr_reader.getOffset() - 1; |
| 1324 | int count = (unsigned int) csb->csb_blr_reader.getByte(); |
| 1325 | RseNode* rse = FB_NEW_POOL(*tdbb->getDefaultPool()) RseNode(*tdbb->getDefaultPool()); |
| 1326 | |
| 1327 | setNodeLineColumn(csb, rse, blrOffset); |
| 1328 | |
| 1329 | if (rse_op == blr_lateral_rse) |
| 1330 | rse->flags |= RseNode::FLAG_LATERAL; |
| 1331 | |
| 1332 | while (--count >= 0) |
| 1333 | rse->rse_relations.add(PAR_parseRecordSource(tdbb, csb)); |
| 1334 | |
| 1335 | while (true) |
| 1336 | { |
| 1337 | const UCHAR op = csb->csb_blr_reader.getByte(); |
| 1338 | |
| 1339 | switch (op) |
| 1340 | { |
| 1341 | case blr_boolean: |
| 1342 | rse->rse_boolean = PAR_parse_boolean(tdbb, csb); |
| 1343 | break; |
| 1344 | |
| 1345 | case blr_first: |
| 1346 | if (rse_op == blr_rs_stream) |
| 1347 | PAR_syntax_error(csb, "RecordSelExpr stream clause"); |
| 1348 | rse->rse_first = PAR_parse_value(tdbb, csb); |
| 1349 | rse->firstRows = true; |
| 1350 | break; |
| 1351 | |
| 1352 | case blr_skip: |
| 1353 | if (rse_op == blr_rs_stream) |
| 1354 | PAR_syntax_error(csb, "RecordSelExpr stream clause"); |
| 1355 | rse->rse_skip = PAR_parse_value(tdbb, csb); |
| 1356 | break; |
| 1357 | |
| 1358 | case blr_sort: |
| 1359 | if (rse_op == blr_rs_stream) |
| 1360 | PAR_syntax_error(csb, "RecordSelExpr stream clause"); |
| 1361 | csb->csb_blr_reader.seekBackward(1); |
| 1362 | rse->rse_sorted = PAR_sort(tdbb, csb, op, false); |
| 1363 | break; |
| 1364 | |
| 1365 | case blr_project: |
| 1366 | if (rse_op == blr_rs_stream) |
| 1367 | PAR_syntax_error(csb, "RecordSelExpr stream clause"); |
| 1368 | csb->csb_blr_reader.seekBackward(1); |
| 1369 | rse->rse_projection = PAR_sort(tdbb, csb, op, false); |
| 1370 | break; |
| 1371 | |
| 1372 | case blr_join_type: |
| 1373 | { |
| 1374 | const USHORT jointype = (USHORT) csb->csb_blr_reader.getByte(); |
| 1375 | rse->rse_jointype = jointype; |
| 1376 | if (jointype != blr_inner && |
no test coverage detected