sql.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #include "sql.h"
  2. #include "sql_query.h"
  3. #include <yql/essentials/parser/proto_ast/collect_issues/collect_issues.h>
  4. #include <yql/essentials/sql/v1/lexer/lexer.h>
  5. #include <yql/essentials/sql/v1/proto_parser/proto_parser.h>
  6. namespace NSQLTranslationV1 {
  7. using namespace NSQLv1Generated;
  8. TAstNode* SqlASTToYql(const google::protobuf::Message& protoAst, TContext& ctx) {
  9. const google::protobuf::Descriptor* d = protoAst.GetDescriptor();
  10. if (d && d->name() != "TSQLv1ParserAST") {
  11. ctx.Error() << "Invalid AST structure: " << d->name() << ", expected TSQLv1ParserAST";
  12. return nullptr;
  13. }
  14. TSqlQuery query(ctx, ctx.Settings.Mode, true);
  15. TNodePtr node(query.Build(static_cast<const TSQLv1ParserAST&>(protoAst)));
  16. try {
  17. if (node && node->Init(ctx, nullptr)) {
  18. return node->Translate(ctx);
  19. }
  20. } catch (const NProtoAST::TTooManyErrors&) {
  21. // do not add error issue, no room for it
  22. }
  23. return nullptr;
  24. }
  25. TAstNode* SqlASTsToYqls(const std::vector<::NSQLv1Generated::TRule_sql_stmt_core>& ast, TContext& ctx) {
  26. TSqlQuery query(ctx, ctx.Settings.Mode, true);
  27. TNodePtr node(query.Build(ast));
  28. try {
  29. if (node && node->Init(ctx, nullptr)) {
  30. return node->Translate(ctx);
  31. }
  32. } catch (const NProtoAST::TTooManyErrors&) {
  33. // do not add error issue, no room for it
  34. }
  35. return nullptr;
  36. }
  37. void SqlASTToYqlImpl(NYql::TAstParseResult& res, const google::protobuf::Message& protoAst,
  38. TContext& ctx) {
  39. YQL_ENSURE(!ctx.Issues.Size());
  40. res.Root = SqlASTToYql(protoAst, ctx);
  41. res.Pool = std::move(ctx.Pool);
  42. if (!res.Root) {
  43. if (ctx.Issues.Size()) {
  44. ctx.IncrementMonCounter("sql_errors", "AstToYqlError");
  45. } else {
  46. ctx.IncrementMonCounter("sql_errors", "AstToYqlSilentError");
  47. ctx.Error() << "Error occurred on parse SQL query, but no error is collected" <<
  48. ", please send this request over bug report into YQL interface or write on yql@ maillist";
  49. }
  50. } else {
  51. ctx.WarnUnusedHints();
  52. }
  53. }
  54. void SqlASTsToYqlsImpl(NYql::TAstParseResult& res, const std::vector<::NSQLv1Generated::TRule_sql_stmt_core>& ast, TContext& ctx) {
  55. res.Root = SqlASTsToYqls(ast, ctx);
  56. res.Pool = std::move(ctx.Pool);
  57. if (!res.Root) {
  58. if (ctx.Issues.Size()) {
  59. ctx.IncrementMonCounter("sql_errors", "AstToYqlError");
  60. } else {
  61. ctx.IncrementMonCounter("sql_errors", "AstToYqlSilentError");
  62. ctx.Error() << "Error occurred on parse SQL query, but no error is collected" <<
  63. ", please send this request over bug report into YQL interface or write on yql@ maillist";
  64. }
  65. } else {
  66. ctx.WarnUnusedHints();
  67. }
  68. }
  69. NYql::TAstParseResult SqlASTToYql(const TString& query,
  70. const google::protobuf::Message& protoAst,
  71. const NSQLTranslation::TSQLHints& hints,
  72. const NSQLTranslation::TTranslationSettings& settings)
  73. {
  74. YQL_ENSURE(IsQueryMode(settings.Mode));
  75. TAstParseResult res;
  76. TContext ctx(settings, hints, res.Issues, query);
  77. SqlASTToYqlImpl(res, protoAst, ctx);
  78. res.ActualSyntaxType = NYql::ESyntaxType::YQLv1;
  79. return res;
  80. }
  81. NYql::TAstParseResult SqlToYql(const TString& query, const NSQLTranslation::TTranslationSettings& settings, NYql::TWarningRules* warningRules)
  82. {
  83. TAstParseResult res;
  84. const TString queryName = "query";
  85. NSQLTranslation::TSQLHints hints;
  86. auto lexer = MakeLexer(settings.AnsiLexer, settings.Antlr4Parser);
  87. YQL_ENSURE(lexer);
  88. if (!CollectSqlHints(*lexer, query, queryName, settings.File, hints, res.Issues, settings.MaxErrors, settings.Antlr4Parser)) {
  89. return res;
  90. }
  91. TContext ctx(settings, hints, res.Issues, query);
  92. NSQLTranslation::TErrorCollectorOverIssues collector(res.Issues, settings.MaxErrors, settings.File);
  93. google::protobuf::Message* ast(SqlAST(query, queryName, collector, settings.AnsiLexer, settings.Antlr4Parser, settings.TestAntlr4, settings.Arena));
  94. if (ast) {
  95. SqlASTToYqlImpl(res, *ast, ctx);
  96. } else {
  97. ctx.IncrementMonCounter("sql_errors", "AstError");
  98. }
  99. if (warningRules) {
  100. *warningRules = ctx.WarningPolicy.GetRules();
  101. ctx.WarningPolicy.Clear();
  102. }
  103. res.ActualSyntaxType = NYql::ESyntaxType::YQLv1;
  104. return res;
  105. }
  106. bool NeedUseForAllStatements(const TRule_sql_stmt_core::AltCase& subquery) {
  107. switch (subquery) {
  108. case TRule_sql_stmt_core::kAltSqlStmtCore1: // pragma
  109. case TRule_sql_stmt_core::kAltSqlStmtCore3: // named nodes
  110. case TRule_sql_stmt_core::kAltSqlStmtCore6: // use
  111. case TRule_sql_stmt_core::kAltSqlStmtCore12: // declare
  112. case TRule_sql_stmt_core::kAltSqlStmtCore13: // import
  113. case TRule_sql_stmt_core::kAltSqlStmtCore14: // export
  114. case TRule_sql_stmt_core::kAltSqlStmtCore18: // define action or subquery
  115. return true;
  116. case TRule_sql_stmt_core::ALT_NOT_SET:
  117. case TRule_sql_stmt_core::kAltSqlStmtCore2: // select
  118. case TRule_sql_stmt_core::kAltSqlStmtCore4: // create table
  119. case TRule_sql_stmt_core::kAltSqlStmtCore5: // drop table
  120. case TRule_sql_stmt_core::kAltSqlStmtCore7: // into table
  121. case TRule_sql_stmt_core::kAltSqlStmtCore8: // commit
  122. case TRule_sql_stmt_core::kAltSqlStmtCore9: // update
  123. case TRule_sql_stmt_core::kAltSqlStmtCore10: // delete
  124. case TRule_sql_stmt_core::kAltSqlStmtCore11: // rollback
  125. case TRule_sql_stmt_core::kAltSqlStmtCore15: // alter table
  126. case TRule_sql_stmt_core::kAltSqlStmtCore16: // alter external table
  127. case TRule_sql_stmt_core::kAltSqlStmtCore17: // do
  128. case TRule_sql_stmt_core::kAltSqlStmtCore19: // if
  129. case TRule_sql_stmt_core::kAltSqlStmtCore20: // for
  130. case TRule_sql_stmt_core::kAltSqlStmtCore21: // values
  131. case TRule_sql_stmt_core::kAltSqlStmtCore22: // create user
  132. case TRule_sql_stmt_core::kAltSqlStmtCore23: // alter user
  133. case TRule_sql_stmt_core::kAltSqlStmtCore24: // create group
  134. case TRule_sql_stmt_core::kAltSqlStmtCore25: // alter group
  135. case TRule_sql_stmt_core::kAltSqlStmtCore26: // drop role
  136. case TRule_sql_stmt_core::kAltSqlStmtCore27: // create object
  137. case TRule_sql_stmt_core::kAltSqlStmtCore28: // alter object
  138. case TRule_sql_stmt_core::kAltSqlStmtCore29: // drop object
  139. case TRule_sql_stmt_core::kAltSqlStmtCore30: // create external data source
  140. case TRule_sql_stmt_core::kAltSqlStmtCore31: // alter external data source
  141. case TRule_sql_stmt_core::kAltSqlStmtCore32: // drop external data source
  142. case TRule_sql_stmt_core::kAltSqlStmtCore33: // create replication
  143. case TRule_sql_stmt_core::kAltSqlStmtCore34: // drop replication
  144. case TRule_sql_stmt_core::kAltSqlStmtCore35: // create topic
  145. case TRule_sql_stmt_core::kAltSqlStmtCore36: // alter topic
  146. case TRule_sql_stmt_core::kAltSqlStmtCore37: // drop topic
  147. case TRule_sql_stmt_core::kAltSqlStmtCore38: // grant permissions
  148. case TRule_sql_stmt_core::kAltSqlStmtCore39: // revoke permissions
  149. case TRule_sql_stmt_core::kAltSqlStmtCore40: // alter table store
  150. case TRule_sql_stmt_core::kAltSqlStmtCore41: // upsert object
  151. case TRule_sql_stmt_core::kAltSqlStmtCore42: // create view
  152. case TRule_sql_stmt_core::kAltSqlStmtCore43: // drop view
  153. case TRule_sql_stmt_core::kAltSqlStmtCore44: // alter replication
  154. case TRule_sql_stmt_core::kAltSqlStmtCore45: // create resource pool
  155. case TRule_sql_stmt_core::kAltSqlStmtCore46: // alter resource pool
  156. case TRule_sql_stmt_core::kAltSqlStmtCore47: // drop resource pool
  157. case TRule_sql_stmt_core::kAltSqlStmtCore48: // create backup collection
  158. case TRule_sql_stmt_core::kAltSqlStmtCore49: // alter backup collection
  159. case TRule_sql_stmt_core::kAltSqlStmtCore50: // drop backup collection
  160. case TRule_sql_stmt_core::kAltSqlStmtCore51: // analyze
  161. case TRule_sql_stmt_core::kAltSqlStmtCore52: // create resource pool classifier
  162. case TRule_sql_stmt_core::kAltSqlStmtCore53: // alter resource pool classifier
  163. case TRule_sql_stmt_core::kAltSqlStmtCore54: // drop resource pool classifier
  164. case TRule_sql_stmt_core::kAltSqlStmtCore55: // backup
  165. case TRule_sql_stmt_core::kAltSqlStmtCore56: // restore
  166. case TRule_sql_stmt_core::kAltSqlStmtCore57: // alter sequence
  167. case TRule_sql_stmt_core::kAltSqlStmtCore58: // create transfer
  168. case TRule_sql_stmt_core::kAltSqlStmtCore59: // alter transfer
  169. case TRule_sql_stmt_core::kAltSqlStmtCore60: // drop transfer
  170. return false;
  171. }
  172. }
  173. TVector<NYql::TAstParseResult> SqlToAstStatements(const TString& queryText, const NSQLTranslation::TTranslationSettings& settings, NYql::TWarningRules* warningRules,
  174. TVector<NYql::TStmtParseInfo>* stmtParseInfo)
  175. {
  176. TVector<TAstParseResult> result;
  177. const TString queryName = "query";
  178. TIssues issues;
  179. NSQLTranslation::TSQLHints hints;
  180. auto lexer = MakeLexer(settings.AnsiLexer, settings.Antlr4Parser);
  181. YQL_ENSURE(lexer);
  182. if (!CollectSqlHints(*lexer, queryText, queryName, settings.File, hints, issues, settings.MaxErrors, settings.Antlr4Parser)) {
  183. return result;
  184. }
  185. TContext ctx(settings, hints, issues, queryText);
  186. NSQLTranslation::TErrorCollectorOverIssues collector(issues, settings.MaxErrors, settings.File);
  187. google::protobuf::Message* astProto(SqlAST(queryText, queryName, collector, settings.AnsiLexer, settings.Antlr4Parser, settings.TestAntlr4, settings.Arena));
  188. if (astProto) {
  189. auto ast = static_cast<const TSQLv1ParserAST&>(*astProto);
  190. const auto& query = ast.GetRule_sql_query();
  191. if (query.Alt_case() == NSQLv1Generated::TRule_sql_query::kAltSqlQuery1) {
  192. std::vector<::NSQLv1Generated::TRule_sql_stmt_core> commonStates;
  193. std::vector<::NSQLv1Generated::TRule_sql_stmt_core> statementResult;
  194. const auto& statements = query.GetAlt_sql_query1().GetRule_sql_stmt_list1();
  195. if (NeedUseForAllStatements(statements.GetRule_sql_stmt2().GetRule_sql_stmt_core2().Alt_case())) {
  196. commonStates.push_back(statements.GetRule_sql_stmt2().GetRule_sql_stmt_core2());
  197. } else {
  198. TContext ctx(settings, hints, issues, queryText);
  199. result.emplace_back();
  200. if (stmtParseInfo) {
  201. stmtParseInfo->push_back({});
  202. }
  203. SqlASTsToYqlsImpl(result.back(), {statements.GetRule_sql_stmt2().GetRule_sql_stmt_core2()}, ctx);
  204. result.back().Issues = std::move(issues);
  205. issues.Clear();
  206. }
  207. for (auto block: statements.GetBlock3()) {
  208. if (NeedUseForAllStatements(block.GetRule_sql_stmt2().GetRule_sql_stmt_core2().Alt_case())) {
  209. commonStates.push_back(block.GetRule_sql_stmt2().GetRule_sql_stmt_core2());
  210. continue;
  211. }
  212. TContext ctx(settings, hints, issues, queryText);
  213. result.emplace_back();
  214. if (stmtParseInfo) {
  215. stmtParseInfo->push_back({});
  216. }
  217. statementResult = commonStates;
  218. statementResult.push_back(block.GetRule_sql_stmt2().GetRule_sql_stmt_core2());
  219. SqlASTsToYqlsImpl(result.back(), statementResult, ctx);
  220. result.back().Issues = std::move(issues);
  221. issues.Clear();
  222. }
  223. }
  224. } else {
  225. ctx.IncrementMonCounter("sql_errors", "AstError");
  226. }
  227. if (warningRules) {
  228. *warningRules = ctx.WarningPolicy.GetRules();
  229. ctx.WarningPolicy.Clear();
  230. }
  231. return result;
  232. }
  233. bool SplitQueryToStatements(const TString& query, TVector<TString>& statements, NYql::TIssues& issues,
  234. const NSQLTranslation::TTranslationSettings& settings) {
  235. auto lexer = NSQLTranslationV1::MakeLexer(settings.AnsiLexer, settings.Antlr4Parser);
  236. TVector<TString> parts;
  237. if (!SplitQueryToStatements(query, lexer, parts, issues)) {
  238. return false;
  239. }
  240. for (auto& currentQuery : parts) {
  241. NYql::TIssues parserIssues;
  242. auto message = NSQLTranslationV1::SqlAST(currentQuery, "Query", parserIssues, NSQLTranslation::SQL_MAX_PARSER_ERRORS,
  243. settings.AnsiLexer, settings.Antlr4Parser, settings.TestAntlr4, settings.Arena);
  244. if (!message) {
  245. // Skip empty statements
  246. continue;
  247. }
  248. statements.push_back(std::move(currentQuery));
  249. }
  250. return true;
  251. }
  252. } // namespace NSQLTranslationV1