| 582 | } |
| 583 | |
| 584 | void SQLParser::parseCommand(Tokenizer& parser) const { |
| 585 | // parse input, for example: array_remove(array_field, [24, 3, 81]) || [11,22] |
| 586 | |
| 587 | auto tok = parser.NextToken(); |
| 588 | if (tok.Text() != "("sv) { |
| 589 | const auto range = parser.Where(tok); |
| 590 | throw SqlParserError(range, "Expected '(' after command name, not {}, {}", tok.Text(), range); |
| 591 | } |
| 592 | |
| 593 | tok = parser.NextToken(); |
| 594 | if (tok.Type() != TokenName) { |
| 595 | const auto range = parser.Where(tok); |
| 596 | throw SqlParserError(range, "Expected field name, but found {} in query, {}", tok.Text(), range); |
| 597 | } |
| 598 | |
| 599 | tok = parser.NextToken(); |
| 600 | if (tok.Text() != ","sv) { |
| 601 | const auto range = parser.Where(tok); |
| 602 | throw SqlParserError(range, "Expected ',' after field parameter, not {}, {}", tok.Text(), range); |
| 603 | } |
| 604 | |
| 605 | // parse item or list of elements or field to be deleted |
| 606 | tok = parser.NextToken(); |
| 607 | // try parse as scalar value |
| 608 | if ((tok.Type() == TokenNumber) || (tok.Type() == TokenString) || (tok.Type() == TokenName)) { |
| 609 | std::ignore = Token2kv(tok, parser, CompositeAllowed_False, FieldAllowed_True, NullAllowed_False); |
| 610 | } else { |
| 611 | parseArray(parser, tok, nullptr); |
| 612 | } |
| 613 | |
| 614 | tok = parser.NextToken(); |
| 615 | if (tok.Text() != ")"sv) { |
| 616 | const auto range = parser.Where(tok); |
| 617 | throw SqlParserError(range, "Expected ')' after command name and params, not {}, {}", tok.Text(), range); |
| 618 | } |
| 619 | |
| 620 | // parse of possible concatenation |
| 621 | tok = parser.PeekToken(Tokenizer::Flags::NoFlags); |
| 622 | while (tok.Text() == "|"sv) { |
| 623 | parser.SkipToken(); |
| 624 | tok = parser.NextToken(); |
| 625 | if (tok.Text() != "|"sv) { |
| 626 | const auto range = parser.Where(tok); |
| 627 | throw SqlParserError(range, "Expected '|', not '{}', {}", tok.Text(), range); |
| 628 | } |
| 629 | tok = parser.NextToken(); |
| 630 | if (tok.Type() == TokenSymbol) { |
| 631 | parseArray(parser, tok, nullptr); |
| 632 | } else if (tok.Type() != TokenName) { |
| 633 | const auto range = parser.Where(tok); |
| 634 | throw SqlParserError(range, "Expected field name, but found {} in query, {}", tok.Text(), range); |
| 635 | } else if (tok.Text() == "array_remove"sv || tok.Text() == "array_remove_once"sv) { |
| 636 | parseCommand(parser); |
| 637 | } |
| 638 | tok = parser.PeekToken(); |
| 639 | } |
| 640 | } |
| 641 | |