| 541 | } |
| 542 | |
| 543 | void SQLParser::parseArray(Tokenizer& parser, const Token& tok, UpdateEntry* updateField) const { |
| 544 | std::string_view tokText = tok.Text(); |
| 545 | if (tokText != "["sv) { |
| 546 | const auto range = parser.Where(); |
| 547 | throw SqlParserError(range, "Expected '[' after field parameter, not {}, {}", tokText, range); |
| 548 | } |
| 549 | |
| 550 | Token nextTok; |
| 551 | for (;;) { |
| 552 | nextTok = parser.NextToken(Tokenizer::Flags::NoFlags); |
| 553 | if (nextTok.Text() == "]"sv) { |
| 554 | if (updateField && updateField->Values().empty()) { |
| 555 | break; |
| 556 | } |
| 557 | const auto range = parser.Where(nextTok); |
| 558 | throw SqlParserError(range, "Expected field value, but found ']' in query, {}", range); |
| 559 | } |
| 560 | if (updateField) { |
| 561 | addUpdateValue(nextTok, parser, *updateField); |
| 562 | } |
| 563 | nextTok = parser.NextToken(Tokenizer::Flags::NoFlags); |
| 564 | if (nextTok.Text() == "]"sv) { |
| 565 | break; |
| 566 | } |
| 567 | if (nextTok.Text() != ","sv) { |
| 568 | const auto range = parser.Where(nextTok); |
| 569 | throw SqlParserError(range, "Expected ']' or ',', but found '{}' in query, {}", nextTok.Text(), range); |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | if (updateField && (updateField->Mode() == FieldModeSetJson)) { |
| 574 | for (const auto& it : updateField->Values()) { |
| 575 | if ((!it.Type().Is<KeyValueType::String>()) || std::string_view(it).front() != '{') { |
| 576 | throw SqlParserError(parser.Where(tok), |
| 577 | "Unexpected variant type in Array: {}. Expecting KeyValueType::String with JSON-content", |
| 578 | it.Type().Name()); |
| 579 | } |
| 580 | } |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | void SQLParser::parseCommand(Tokenizer& parser) const { |
| 585 | // parse input, for example: array_remove(array_field, [24, 3, 81]) || [11,22] |
nothing calls this directly
no test coverage detected