aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1/complete/analysis/global/use.cpp
diff options
context:
space:
mode:
authorvityaman <vityaman.dev@yandex.ru>2025-05-20 12:50:28 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2025-05-20 13:07:06 +0300
commit16630d4dfad772e0108e694f76f922e486cd6439 (patch)
tree9502ff9057dfb71a94154f66a3e6452bf684c8fd /yql/essentials/sql/v1/complete/analysis/global/use.cpp
parent2cca5c2b53580983c51f00239859e45d4bc32836 (diff)
downloadydb-16630d4dfad772e0108e694f76f922e486cd6439.tar.gz
YQL-19747: Support USE statement
Introduce global analysis which will be extended with more ParseTree analysis later. --- - Related to `YQL-19747` - Related to https://github.com/vityaman/ydb/issues/40 --- Pull Request resolved: https://github.com/ytsaurus/ytsaurus/pull/1281 commit_hash:848fb3fdd6bc9612769c47d66198fca018ff465f
Diffstat (limited to 'yql/essentials/sql/v1/complete/analysis/global/use.cpp')
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/use.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/yql/essentials/sql/v1/complete/analysis/global/use.cpp b/yql/essentials/sql/v1/complete/analysis/global/use.cpp
new file mode 100644
index 00000000000..da7dc6a5751
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/analysis/global/use.cpp
@@ -0,0 +1,96 @@
+#include "use.h"
+
+namespace NSQLComplete {
+
+ namespace {
+
+ class TVisitor: public SQLv1Antlr4BaseVisitor {
+ public:
+ TVisitor(antlr4::TokenStream* tokens, size_t cursorPosition)
+ : Tokens_(tokens)
+ , CursorPosition_(cursorPosition)
+ {
+ }
+
+ std::any visitSql_stmt_core(SQLv1::Sql_stmt_coreContext* ctx) override {
+ if (ctx->use_stmt() || IsEnclosing(ctx)) {
+ return visitChildren(ctx);
+ }
+ return {};
+ }
+
+ std::any visitUse_stmt(SQLv1::Use_stmtContext* ctx) override {
+ SQLv1::Cluster_exprContext* expr = ctx->cluster_expr();
+ if (!expr) {
+ return {};
+ }
+
+ std::string provider;
+ std::string cluster;
+
+ if (SQLv1::An_idContext* ctx = expr->an_id()) {
+ provider = ctx->getText();
+ }
+
+ if (SQLv1::Pure_column_or_namedContext* ctx = expr->pure_column_or_named()) {
+ cluster = ctx->getText();
+ }
+
+ if (cluster.empty()) {
+ return {};
+ }
+
+ return TUseContext{
+ .Provider = std::move(provider),
+ .Cluster = std::move(cluster),
+ };
+ }
+
+ std::any aggregateResult(std::any aggregate, std::any nextResult) override {
+ if (nextResult.has_value()) {
+ return nextResult;
+ }
+ return aggregate;
+ }
+
+ bool shouldVisitNextChild(antlr4::tree::ParseTree* node, const std::any& /*currentResult*/) override {
+ return TextInterval(node).a < static_cast<ssize_t>(CursorPosition_);
+ }
+
+ private:
+ bool IsEnclosing(antlr4::tree::ParseTree* tree) const {
+ return TextInterval(tree).properlyContains(CursorInterval());
+ }
+
+ antlr4::misc::Interval TextInterval(antlr4::tree::ParseTree* tree) const {
+ auto tokens = tree->getSourceInterval();
+ if (tokens.b == -1) {
+ tokens.b = tokens.a;
+ }
+ return antlr4::misc::Interval(
+ Tokens_->get(tokens.a)->getStartIndex(),
+ Tokens_->get(tokens.b)->getStopIndex());
+ }
+
+ antlr4::misc::Interval CursorInterval() const {
+ return antlr4::misc::Interval(CursorPosition_, CursorPosition_);
+ }
+
+ antlr4::TokenStream* Tokens_;
+ size_t CursorPosition_;
+ };
+
+ } // namespace
+
+ TMaybe<TUseContext> FindUseStatement(
+ SQLv1::Sql_queryContext* ctx,
+ antlr4::TokenStream* tokens,
+ size_t cursorPosition) {
+ std::any result = TVisitor(tokens, cursorPosition).visit(ctx);
+ if (!result.has_value()) {
+ return Nothing();
+ }
+ return std::any_cast<TUseContext>(result);
+ }
+
+} // namespace NSQLComplete