hints.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include "hints.h"
  2. #include "parse_hints_impl.h"
  3. #include <yql/essentials/utils/yql_panic.h>
  4. #include <util/string/escape.h>
  5. namespace NSQLTranslation {
  6. using NYql::TPosition;
  7. TString TSQLHint::ToString() const {
  8. TString result;
  9. TStringOutput out(result);
  10. Out(out);
  11. return result;
  12. }
  13. void TSQLHint::Out(IOutputStream& o) const {
  14. o << "\"" << EscapeC(Name) << "\":{";
  15. for (size_t i = 0; i < Values.size(); ++i) {
  16. o << "\"" << EscapeC(Values[i]) << "\"";
  17. if (i + 1 < Values.size()) {
  18. o << ",";
  19. }
  20. }
  21. o << "}";
  22. }
  23. namespace {
  24. class TTokenProcessor {
  25. public:
  26. TTokenProcessor(const TString& queryFile, TSQLHints& hints, bool utf8Aware)
  27. : QueryFile(queryFile)
  28. , Hints(hints)
  29. , Utf8Aware(utf8Aware)
  30. {}
  31. TPosition ExtractPosition(const TParsedToken& token) const {
  32. return TPosition(token.LinePos + 1, token.Line, QueryFile);
  33. }
  34. void ProcessToken(TParsedToken&& token) {
  35. if (token.Name == "EOF") {
  36. return;
  37. }
  38. auto pos = ExtractPosition(token);
  39. YQL_ENSURE(!PrevNonCommentPos.Defined() || *PrevNonCommentPos < pos, "Tokens positions should increase monotonically");
  40. if (token.Name == "WS") {
  41. return;
  42. }
  43. if (token.Name != "COMMENT") {
  44. PrevNonCommentPos = pos;
  45. return;
  46. }
  47. if (!PrevNonCommentPos) {
  48. // skip leading comments
  49. return;
  50. }
  51. TVector<TSQLHint> currentHints = NDetail::ParseSqlHints(pos, token.Content, Utf8Aware);
  52. if (currentHints.empty()) {
  53. // no hints here
  54. return;
  55. }
  56. auto& target = Hints[*PrevNonCommentPos];
  57. target.insert(target.end(), currentHints.begin(), currentHints.end());
  58. }
  59. private:
  60. TMaybe<TPosition> PrevNonCommentPos;
  61. const TString QueryFile;
  62. TSQLHints& Hints;
  63. const bool Utf8Aware;
  64. };
  65. }
  66. bool CollectSqlHints(ILexer& lexer, const TString& query, const TString& queryName,
  67. const TString& queryFile, TSQLHints& hints, NYql::TIssues& issues, size_t maxErrors, bool utf8Aware) {
  68. TTokenProcessor tp(queryFile, hints, utf8Aware);
  69. return lexer.Tokenize(query, queryName, [&tp](TParsedToken&& token) { tp.ProcessToken(std::move(token)); }, issues, maxErrors);
  70. }
  71. }