| 480 | } |
| 481 | |
| 482 | static void addUpdateValue(const Token& tok, Tokenizer& parser, UpdateEntry& updateField) { |
| 483 | if (tok.Type() == TokenString) { |
| 484 | updateField.Values().push_back(Token2kv(tok, parser, CompositeAllowed_False, FieldAllowed_False, NullAllowed_True)); |
| 485 | } else { |
| 486 | if (tok.Text() == "null"sv) { |
| 487 | updateField.Values().push_back(Variant()); |
| 488 | } else if (tok.Text() == "{"sv) { |
| 489 | try { |
| 490 | const size_t jsonPos = parser.GetPrevPos(); |
| 491 | std::string json(parser.Begin() + jsonPos, parser.Length() - jsonPos); |
| 492 | size_t jsonLength = 0; |
| 493 | gason::JsonParser jsonParser; |
| 494 | jsonParser.Parse(giftStr(json), &jsonLength); |
| 495 | updateField.Values().emplace_back(Variant(std::string(parser.Begin() + jsonPos, jsonLength))); |
| 496 | updateField.SetMode(FieldModeSetJson); |
| 497 | parser.SetPos(jsonPos + jsonLength); |
| 498 | } catch (const gason::Exception& e) { |
| 499 | const auto range = parser.Where(tok); |
| 500 | throw SqlParserError(range, "{}, in query {}", e.what(), range); |
| 501 | } |
| 502 | } else { |
| 503 | auto eof = [](Tokenizer& parser, bool& inArray) -> bool { |
| 504 | if (parser.End()) { |
| 505 | return true; |
| 506 | } |
| 507 | auto nextTok = parser.PeekToken(); |
| 508 | bool result = (nextTok.Text() == "where"sv) || (nextTok.Text() == "order"sv) || (nextTok.Text() == "limit"sv) || |
| 509 | (nextTok.Text() == "offset"sv) || (!inArray && nextTok.Text() == "]"sv) || |
| 510 | (!inArray && nextTok.Text() == ","sv); |
| 511 | if (nextTok.Text() == "["sv && !inArray) { |
| 512 | inArray = true; |
| 513 | } |
| 514 | if (nextTok.Text() == "]"sv && inArray) { |
| 515 | inArray = false; |
| 516 | } |
| 517 | return result; |
| 518 | }; |
| 519 | int count = 0; |
| 520 | std::string expression(tok.Text()); |
| 521 | bool inArray = false; |
| 522 | while (!eof(parser, inArray)) { |
| 523 | auto nextTok = parser.NextToken(Tokenizer::Flags::TreatSignAsToken); |
| 524 | expression += (nextTok.Type() == TokenString) ? ('\'' + std::string{nextTok.Text()} + '\'') : std::string{nextTok.Text()}; |
| 525 | ++count; |
| 526 | } |
| 527 | if (count > 0) { |
| 528 | updateField.Values().emplace_back(std::move(expression)); |
| 529 | updateField.SetIsExpression(true); |
| 530 | } else { |
| 531 | try { |
| 532 | Variant val = Token2kv(tok, parser, CompositeAllowed_False, FieldAllowed_False, NullAllowed_True); |
| 533 | updateField.Values().emplace_back(std::move(val)); |
| 534 | } catch (const Error&) { |
| 535 | updateField.Values().emplace_back(std::move(expression)); |
| 536 | updateField.SetIsExpression(true); |
| 537 | } |
| 538 | } |
| 539 | } |
no test coverage detected