sql.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 google::protobuf::Message& protoAst,
  70. const NSQLTranslation::TSQLHints& hints,
  71. const NSQLTranslation::TTranslationSettings& settings)
  72. {
  73. YQL_ENSURE(IsQueryMode(settings.Mode));
  74. TAstParseResult res;
  75. TContext ctx(settings, hints, res.Issues);
  76. SqlASTToYqlImpl(res, protoAst, ctx);
  77. res.ActualSyntaxType = NYql::ESyntaxType::YQLv1;
  78. return res;
  79. }
  80. NYql::TAstParseResult SqlToYql(const TString& query, const NSQLTranslation::TTranslationSettings& settings, NYql::TWarningRules* warningRules)
  81. {
  82. TAstParseResult res;
  83. const TString queryName = "query";
  84. NSQLTranslation::TSQLHints hints;
  85. auto lexer = MakeLexer(settings.AnsiLexer, settings.Antlr4Parser);
  86. YQL_ENSURE(lexer);
  87. if (!CollectSqlHints(*lexer, query, queryName, settings.File, hints, res.Issues, settings.MaxErrors, settings.Antlr4Parser)) {
  88. return res;
  89. }
  90. TContext ctx(settings, hints, res.Issues);
  91. NSQLTranslation::TErrorCollectorOverIssues collector(res.Issues, settings.MaxErrors, settings.File);
  92. google::protobuf::Message* ast(SqlAST(query, queryName, collector, settings.AnsiLexer, settings.Antlr4Parser, settings.TestAntlr4, settings.Arena));
  93. if (ast) {
  94. SqlASTToYqlImpl(res, *ast, ctx);
  95. } else {
  96. ctx.IncrementMonCounter("sql_errors", "AstError");
  97. }
  98. if (warningRules) {
  99. *warningRules = ctx.WarningPolicy.GetRules();
  100. ctx.WarningPolicy.Clear();
  101. }
  102. res.ActualSyntaxType = NYql::ESyntaxType::YQLv1;
  103. return res;
  104. }
  105. bool NeedUseForAllStatements(const TRule_sql_stmt_core::AltCase& subquery) {
  106. switch (subquery) {
  107. case TRule_sql_stmt_core::kAltSqlStmtCore1: // pragma
  108. case TRule_sql_stmt_core::kAltSqlStmtCore3: // named nodes
  109. case TRule_sql_stmt_core::kAltSqlStmtCore6: // use
  110. case TRule_sql_stmt_core::kAltSqlStmtCore12: // declare
  111. case TRule_sql_stmt_core::kAltSqlStmtCore13: // import
  112. case TRule_sql_stmt_core::kAltSqlStmtCore14: // export
  113. case TRule_sql_stmt_core::kAltSqlStmtCore18: // define action or subquery
  114. return true;
  115. case TRule_sql_stmt_core::ALT_NOT_SET:
  116. case TRule_sql_stmt_core::kAltSqlStmtCore2: // select
  117. case TRule_sql_stmt_core::kAltSqlStmtCore4: // create table
  118. case TRule_sql_stmt_core::kAltSqlStmtCore5: // drop table
  119. case TRule_sql_stmt_core::kAltSqlStmtCore7: // into table
  120. case TRule_sql_stmt_core::kAltSqlStmtCore8: // commit
  121. case TRule_sql_stmt_core::kAltSqlStmtCore9: // update
  122. case TRule_sql_stmt_core::kAltSqlStmtCore10: // delete
  123. case TRule_sql_stmt_core::kAltSqlStmtCore11: // rollback
  124. case TRule_sql_stmt_core::kAltSqlStmtCore15: // alter table
  125. case TRule_sql_stmt_core::kAltSqlStmtCore16: // alter external table
  126. case TRule_sql_stmt_core::kAltSqlStmtCore17: // do
  127. case TRule_sql_stmt_core::kAltSqlStmtCore19: // if
  128. case TRule_sql_stmt_core::kAltSqlStmtCore20: // for
  129. case TRule_sql_stmt_core::kAltSqlStmtCore21: // values
  130. case TRule_sql_stmt_core::kAltSqlStmtCore22: // create user
  131. case TRule_sql_stmt_core::kAltSqlStmtCore23: // alter user
  132. case TRule_sql_stmt_core::kAltSqlStmtCore24: // create group
  133. case TRule_sql_stmt_core::kAltSqlStmtCore25: // alter group
  134. case TRule_sql_stmt_core::kAltSqlStmtCore26: // drop role
  135. case TRule_sql_stmt_core::kAltSqlStmtCore27: // create object
  136. case TRule_sql_stmt_core::kAltSqlStmtCore28: // alter object
  137. case TRule_sql_stmt_core::kAltSqlStmtCore29: // drop object
  138. case TRule_sql_stmt_core::kAltSqlStmtCore30: // create external data source
  139. case TRule_sql_stmt_core::kAltSqlStmtCore31: // alter external data source
  140. case TRule_sql_stmt_core::kAltSqlStmtCore32: // drop external data source
  141. case TRule_sql_stmt_core::kAltSqlStmtCore33: // create replication
  142. case TRule_sql_stmt_core::kAltSqlStmtCore34: // drop replication
  143. case TRule_sql_stmt_core::kAltSqlStmtCore35: // create topic
  144. case TRule_sql_stmt_core::kAltSqlStmtCore36: // alter topic
  145. case TRule_sql_stmt_core::kAltSqlStmtCore37: // drop topic
  146. case TRule_sql_stmt_core::kAltSqlStmtCore38: // grant permissions
  147. case TRule_sql_stmt_core::kAltSqlStmtCore39: // revoke permissions
  148. case TRule_sql_stmt_core::kAltSqlStmtCore40: // alter table store
  149. case TRule_sql_stmt_core::kAltSqlStmtCore41: // upsert object
  150. case TRule_sql_stmt_core::kAltSqlStmtCore42: // create view
  151. case TRule_sql_stmt_core::kAltSqlStmtCore43: // drop view
  152. case TRule_sql_stmt_core::kAltSqlStmtCore44: // alter replication
  153. case TRule_sql_stmt_core::kAltSqlStmtCore45: // create resource pool
  154. case TRule_sql_stmt_core::kAltSqlStmtCore46: // alter resource pool
  155. case TRule_sql_stmt_core::kAltSqlStmtCore47: // drop resource pool
  156. case TRule_sql_stmt_core::kAltSqlStmtCore48: // create backup collection
  157. case TRule_sql_stmt_core::kAltSqlStmtCore49: // alter backup collection
  158. case TRule_sql_stmt_core::kAltSqlStmtCore50: // drop backup collection
  159. case TRule_sql_stmt_core::kAltSqlStmtCore51: // analyze
  160. case TRule_sql_stmt_core::kAltSqlStmtCore52: // create resource pool classifier
  161. case TRule_sql_stmt_core::kAltSqlStmtCore53: // alter resource pool classifier
  162. case TRule_sql_stmt_core::kAltSqlStmtCore54: // drop resource pool classifier
  163. case TRule_sql_stmt_core::kAltSqlStmtCore55: // backup
  164. case TRule_sql_stmt_core::kAltSqlStmtCore56: // restore
  165. case TRule_sql_stmt_core::kAltSqlStmtCore57: // alter sequence
  166. return false;
  167. }
  168. }
  169. TVector<NYql::TAstParseResult> SqlToAstStatements(const TString& query, const NSQLTranslation::TTranslationSettings& settings, NYql::TWarningRules* warningRules,
  170. TVector<NYql::TStmtParseInfo>* stmtParseInfo)
  171. {
  172. TVector<TAstParseResult> result;
  173. const TString queryName = "query";
  174. TIssues issues;
  175. NSQLTranslation::TSQLHints hints;
  176. auto lexer = MakeLexer(settings.AnsiLexer, settings.Antlr4Parser);
  177. YQL_ENSURE(lexer);
  178. if (!CollectSqlHints(*lexer, query, queryName, settings.File, hints, issues, settings.MaxErrors, settings.Antlr4Parser)) {
  179. return result;
  180. }
  181. TContext ctx(settings, hints, issues);
  182. NSQLTranslation::TErrorCollectorOverIssues collector(issues, settings.MaxErrors, settings.File);
  183. google::protobuf::Message* astProto(SqlAST(query, queryName, collector, settings.AnsiLexer, settings.Antlr4Parser, settings.TestAntlr4, settings.Arena));
  184. if (astProto) {
  185. auto ast = static_cast<const TSQLv1ParserAST&>(*astProto);
  186. const auto& query = ast.GetRule_sql_query();
  187. if (query.Alt_case() == NSQLv1Generated::TRule_sql_query::kAltSqlQuery1) {
  188. std::vector<::NSQLv1Generated::TRule_sql_stmt_core> commonStates;
  189. std::vector<::NSQLv1Generated::TRule_sql_stmt_core> statementResult;
  190. const auto& statements = query.GetAlt_sql_query1().GetRule_sql_stmt_list1();
  191. if (NeedUseForAllStatements(statements.GetRule_sql_stmt2().GetRule_sql_stmt_core2().Alt_case())) {
  192. commonStates.push_back(statements.GetRule_sql_stmt2().GetRule_sql_stmt_core2());
  193. } else {
  194. TContext ctx(settings, hints, issues);
  195. result.emplace_back();
  196. if (stmtParseInfo) {
  197. stmtParseInfo->push_back({});
  198. }
  199. SqlASTsToYqlsImpl(result.back(), {statements.GetRule_sql_stmt2().GetRule_sql_stmt_core2()}, ctx);
  200. result.back().Issues = std::move(issues);
  201. issues.Clear();
  202. }
  203. for (auto block: statements.GetBlock3()) {
  204. if (NeedUseForAllStatements(block.GetRule_sql_stmt2().GetRule_sql_stmt_core2().Alt_case())) {
  205. commonStates.push_back(block.GetRule_sql_stmt2().GetRule_sql_stmt_core2());
  206. continue;
  207. }
  208. TContext ctx(settings, hints, issues);
  209. result.emplace_back();
  210. if (stmtParseInfo) {
  211. stmtParseInfo->push_back({});
  212. }
  213. statementResult = commonStates;
  214. statementResult.push_back(block.GetRule_sql_stmt2().GetRule_sql_stmt_core2());
  215. SqlASTsToYqlsImpl(result.back(), statementResult, ctx);
  216. result.back().Issues = std::move(issues);
  217. issues.Clear();
  218. }
  219. }
  220. } else {
  221. ctx.IncrementMonCounter("sql_errors", "AstError");
  222. }
  223. if (warningRules) {
  224. *warningRules = ctx.WarningPolicy.GetRules();
  225. ctx.WarningPolicy.Clear();
  226. }
  227. return result;
  228. }
  229. } // namespace NSQLTranslationV1