MCPcopy Create free account
hub / github.com/Restream/reindexer / parseOrderBy

Method parseOrderBy

cpp_src/core/query/sql/sqlparser.cc:400–464  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

398
399template <typename Sortable>
400void SQLParser::parseOrderBy(Tokenizer& parser, Sortable& sortable) {
401 // Just skip token (BY)
402 std::ignore = peekSqlToken(parser, BySqlToken);
403 parser.SkipToken();
404 Token tok, nameWithCase;
405 for (;;) {
406 nameWithCase = peekSqlToken(parser, FieldNameSqlToken, false);
407 if (nameWithCase.Type() != TokenName && nameWithCase.Type() != TokenString) {
408 const auto range = parser.Where(nameWithCase);
409 throw SqlParserError(range, "Expected name, but found '{}' in query, {}", nameWithCase.Text(), range);
410 }
411 tok = parser.NextToken(Tokenizer::Flags::InOrderBy);
412 std::string sortExpression(tok.Text());
413 if (sortExpression.empty()) {
414 const auto range = parser.Where(tok);
415 throw SqlParserError(range, "Order by expression should not be empty, {}", range);
416 }
417 tok = peekSqlToken(parser, SortDirectionSqlToken);
418 std::vector<Variant> forcedSortOrder;
419 if (tok.Text() == "("sv && iequals(nameWithCase.Text(), "field"sv)) {
420 if constexpr (std::is_same_v<Sortable, AggregateEntry>) {
421 const auto range = parser.Where(tok);
422 throw SqlParserError(range, "Forced sort order is not available in aggregation sort");
423 }
424 parser.SkipToken();
425 nameWithCase = peekSqlToken(parser, FieldNameSqlToken, false);
426 if (nameWithCase.Type() != TokenName) {
427 const auto range = parser.Where(nameWithCase);
428 throw SqlParserError(range, "Expected name, but found '{}' in query, {}", nameWithCase.Text(), range);
429 }
430 sortExpression = nameWithCase.Text();
431 tok = parser.NextToken(Tokenizer::Flags::NoFlags);
432 for (;;) {
433 tok = parser.NextToken();
434 if (tok.Text() == ")"sv) {
435 break;
436 }
437 if (tok.Text() != ","sv) {
438 const auto range = parser.Where(tok);
439 throw SqlParserError(range, "Expected ')' or ',', but found '{}' in query, {}", tok.Text(), range);
440 }
441 tok = parser.NextToken();
442 forcedSortOrder.push_back(Token2kv(tok, parser, CompositeAllowed_True, FieldAllowed_False, NullAllowed_False));
443 }
444 tok = parser.PeekToken();
445 }
446
447 bool desc = false;
448 if (tok.Text() == "asc"sv || tok.Text() == "desc"sv) {
449 desc = tok.Text() == "desc"sv;
450 parser.SkipToken();
451 }
452 if constexpr (std::is_same_v<Sortable, AggregateEntry>) {
453 sortable.Sort(std::move(sortExpression), desc);
454 } else {
455 sortable.Sort(std::move(sortExpression), desc, std::move(forcedSortOrder));
456 }
457

Callers

nothing calls this directly

Calls 11

SqlParserErrorClass · 0.85
iequalsFunction · 0.85
Token2kvFunction · 0.85
SkipTokenMethod · 0.80
PeekTokenMethod · 0.80
TypeMethod · 0.65
WhereMethod · 0.45
NextTokenMethod · 0.45
emptyMethod · 0.45
push_backMethod · 0.45
SortMethod · 0.45

Tested by

no test coverage detected