Parse post-WHERE clauses: additional MATCH, WITH, RETURN, UNION */
| 1793 | |
| 1794 | /* Parse post-WHERE clauses: additional MATCH, WITH, RETURN, UNION */ |
| 1795 | static int parse_post_where(parser_t *p, cbm_query_t *q, // NOLINT(misc-no-recursion) |
| 1796 | int *pat_cap) { |
| 1797 | /* More MATCH / OPTIONAL MATCH after WHERE */ |
| 1798 | if (parse_match_chain(p, q, pat_cap) < 0) { |
| 1799 | return CBM_NOT_FOUND; |
| 1800 | } |
| 1801 | /* Check for unsupported keywords */ |
| 1802 | const char *unsup = unsupported_clause_error(peek(p)->type); |
| 1803 | if (unsup) { |
| 1804 | snprintf(p->error, sizeof(p->error), "%s", unsup); |
| 1805 | return CBM_NOT_FOUND; |
| 1806 | } |
| 1807 | /* Optional WITH clause (standalone, not STARTS WITH) */ |
| 1808 | if (check(p, TOK_WITH) && |
| 1809 | (p->pos < PAIR_LEN || p->tokens[p->pos - SKIP_ONE].type != TOK_STARTS)) { |
| 1810 | if (parse_return_or_with(p, &q->with_clause, true) < 0) { |
| 1811 | return CBM_NOT_FOUND; |
| 1812 | } |
| 1813 | if (parse_where(p, &q->post_with_where) < 0) { |
| 1814 | return CBM_NOT_FOUND; |
| 1815 | } |
| 1816 | } |
| 1817 | /* Optional RETURN */ |
| 1818 | if (parse_return(p, &q->ret) < 0) { |
| 1819 | return CBM_NOT_FOUND; |
| 1820 | } |
| 1821 | /* UNION [ALL] */ |
| 1822 | if (check(p, TOK_UNION)) { |
| 1823 | advance(p); |
| 1824 | q->union_all = match(p, TOK_ALL); |
| 1825 | cbm_parse_result_t sub = {0}; |
| 1826 | if (cbm_parse(&p->tokens[p->pos], p->count - p->pos, &sub) < 0) { |
| 1827 | if (sub.error) { |
| 1828 | snprintf(p->error, sizeof(p->error), "%s", sub.error); |
| 1829 | } |
| 1830 | cbm_parse_free(&sub); |
| 1831 | return CBM_NOT_FOUND; |
| 1832 | } |
| 1833 | q->union_next = sub.query; |
| 1834 | sub.query = NULL; |
| 1835 | cbm_parse_free(&sub); |
| 1836 | } |
| 1837 | return 0; |
| 1838 | } |
| 1839 | |
| 1840 | int cbm_parse(const cbm_token_t *tokens, int token_count, // NOLINT(misc-no-recursion) |
| 1841 | cbm_parse_result_t *out) { |
no test coverage detected