diff options
author | vvvv <vvvv@yandex-team.com> | 2024-11-25 17:30:29 +0300 |
---|---|---|
committer | vvvv <vvvv@yandex-team.com> | 2024-11-25 17:46:04 +0300 |
commit | 3a23d3a68f1d5142c0b82bdcfa3d11364e5811d2 (patch) | |
tree | 78ce2ccbcd6b6e03420bb6b25ff5fe996d5e53b7 | |
parent | a5aa9bbc147faa631997882c70816df0c81ade09 (diff) | |
download | ydb-3a23d3a68f1d5142c0b82bdcfa3d11364e5811d2.tar.gz |
Moved yql/public/fastcheck YQL-19206
init
commit_hash:947826545f94e3ccee28dda8896937b9aebac9bb
-rw-r--r-- | yql/essentials/public/fastcheck/fastcheck.cpp | 95 | ||||
-rw-r--r-- | yql/essentials/public/fastcheck/fastcheck.h | 21 | ||||
-rw-r--r-- | yql/essentials/public/fastcheck/fastcheck_ut.cpp | 120 | ||||
-rw-r--r-- | yql/essentials/public/fastcheck/ut/ya.make | 7 | ||||
-rw-r--r-- | yql/essentials/public/fastcheck/ya.make | 22 | ||||
-rw-r--r-- | yql/essentials/public/ya.make | 1 |
6 files changed, 266 insertions, 0 deletions
diff --git a/yql/essentials/public/fastcheck/fastcheck.cpp b/yql/essentials/public/fastcheck/fastcheck.cpp new file mode 100644 index 0000000000..46870d95b3 --- /dev/null +++ b/yql/essentials/public/fastcheck/fastcheck.cpp @@ -0,0 +1,95 @@ +#include "fastcheck.h" +#include <yql/essentials/ast/yql_ast.h> +#include <yql/essentials/ast/yql_expr.h> +#include <yql/essentials/core/services/mounts/yql_mounts.h> +#include <yql/essentials/core/user_data/yql_user_data.h> +#include <yql/essentials/core/yql_type_annotation.h> +#include <yql/essentials/core/yql_user_data_storage.h> +#include <yql/essentials/sql/sql.h> + +namespace NYql { +namespace NFastCheck { + +bool CheckProgram(const TString& program, const TOptions& options, TIssues& errors) { + TAstParseResult astRes; + if (options.IsSql) { + NSQLTranslation::TTranslationSettings settings; + settings.ClusterMapping = options.ClusterMapping; + settings.SyntaxVersion = options.SyntaxVersion; + settings.V0Behavior = NSQLTranslation::EV0Behavior::Disable; + if (options.IsLibrary) { + settings.Mode = NSQLTranslation::ESqlMode::LIBRARY; + } + + astRes = SqlToYql(program, settings); + } else { + astRes = ParseAst(program); + } + + if (!astRes.IsOk()) { + errors = std::move(astRes.Issues); + return false; + } + + if (options.IsLibrary) { + return true; + } + + if (options.ParseOnly) { + // parse SQL libs + for (const auto& x : options.SqlLibs) { + NSQLTranslation::TTranslationSettings settings; + settings.ClusterMapping = options.ClusterMapping; + settings.SyntaxVersion = options.SyntaxVersion; + settings.V0Behavior = NSQLTranslation::EV0Behavior::Disable; + settings.File = x.first; + settings.Mode = NSQLTranslation::ESqlMode::LIBRARY; + + astRes = SqlToYql(x.second, settings); + if (!astRes.IsOk()) { + errors = std::move(astRes.Issues); + return false; + } + } + + return true; + } + + TVector<NUserData::TUserData> userData; + for (const auto& x : options.SqlLibs) { + NUserData::TUserData data; + data.Type_ = NUserData::EType::LIBRARY; + data.Disposition_ = NUserData::EDisposition::INLINE; + data.Name_ = x.first; + data.Content_ = x.second; + userData.push_back(data); + } + + TExprContext libCtx; + libCtx.IssueManager.AddIssues(std::move(astRes.Issues)); + IModuleResolver::TPtr moduleResolver; + TUserDataTable userDataTable = GetYqlModuleResolver(libCtx, moduleResolver, userData, options.ClusterMapping, {}); + if (!userDataTable) { + errors = libCtx.IssueManager.GetIssues(); + libCtx.IssueManager.Reset(); + return false; + } + + auto userDataStorage = MakeIntrusive<TUserDataStorage>(nullptr, userDataTable, nullptr, nullptr); + if (auto modules = dynamic_cast<TModuleResolver*>(moduleResolver.get())) { + modules->AttachUserData(userDataStorage); + } + + TExprContext exprCtx(libCtx.NextUniqueId); + TExprNode::TPtr exprRoot; + if (!CompileExpr(*astRes.Root, exprRoot, exprCtx, moduleResolver.get(), nullptr, false, Max<ui32>(), options.SyntaxVersion)) { + errors = exprCtx.IssueManager.GetIssues(); + exprCtx.IssueManager.Reset(); + return false; + } + + return true; +} + +} +} diff --git a/yql/essentials/public/fastcheck/fastcheck.h b/yql/essentials/public/fastcheck/fastcheck.h new file mode 100644 index 0000000000..c204302615 --- /dev/null +++ b/yql/essentials/public/fastcheck/fastcheck.h @@ -0,0 +1,21 @@ +#pragma once +#include <yql/essentials/ast/yql_errors.h> +#include <util/generic/hash.h> +#include <yql/essentials/providers/common/provider/yql_provider_names.h> + +namespace NYql { +namespace NFastCheck { + +struct TOptions { + bool IsSql = true; + bool ParseOnly = false; + THashMap<TString, TString> ClusterMapping; + ui16 SyntaxVersion = 1; + bool IsLibrary = false; + THashMap<TString, TString> SqlLibs = {}; // mapping file name => SQL +}; + +bool CheckProgram(const TString& program, const TOptions& options, TIssues& errors); + +} +} diff --git a/yql/essentials/public/fastcheck/fastcheck_ut.cpp b/yql/essentials/public/fastcheck/fastcheck_ut.cpp new file mode 100644 index 0000000000..79c4d30d4f --- /dev/null +++ b/yql/essentials/public/fastcheck/fastcheck_ut.cpp @@ -0,0 +1,120 @@ +#include "fastcheck.h" +#include <library/cpp/testing/unittest/registar.h> + +using namespace NYql; +using namespace NYql::NFastCheck; + +Y_UNIT_TEST_SUITE(TFastCheckTests) { + Y_UNIT_TEST(ParsePureYqlGood) { + TOptions options; + options.IsSql = false; + options.ParseOnly = true; + TIssues errors; + UNIT_ASSERT(CheckProgram("(return world)", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(0, errors.Size()); + } + + Y_UNIT_TEST(ParsePureYqlBad) { + TOptions options; + options.IsSql = false; + options.ParseOnly = true; + TIssues errors; + UNIT_ASSERT(CheckProgram("(return world1)", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(0, errors.Size()); + } + + Y_UNIT_TEST(ParsePureSqlGood) { + TOptions options; + options.IsSql = true; + options.ParseOnly = true; + TIssues errors; + UNIT_ASSERT(CheckProgram("select 1", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(0, errors.Size()); + } + + Y_UNIT_TEST(ParsePureSqlBad) { + TOptions options; + options.IsSql = true; + options.ParseOnly = true; + TIssues errors; + UNIT_ASSERT(!CheckProgram("select1", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(1, errors.Size()); + } + + Y_UNIT_TEST(CompilePureYqlBad) { + TOptions options; + options.IsSql = false; + options.ParseOnly = false; + TIssues errors; + UNIT_ASSERT(!CheckProgram("(return world1)", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(1, errors.Size()); + } + + Y_UNIT_TEST(CompileTableSqlGood) { + TOptions options; + options.IsSql = true; + options.ParseOnly = false; + options.ClusterMapping["plato"] = YtProviderName; + TIssues errors; + UNIT_ASSERT(CheckProgram("select key,count(*) from plato.Input group by key", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(0, errors.Size()); + } + + Y_UNIT_TEST(CompileTableSqlBad) { + TOptions options; + options.IsSql = true; + options.ParseOnly = false; + TIssues errors; + UNIT_ASSERT(!CheckProgram("select key,count(*) from plato.Input", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(1, errors.Size()); + } + + Y_UNIT_TEST(CompileLibrary) { + TOptions options; + options.IsSql = true; + options.IsLibrary = true; + TIssues errors; + UNIT_ASSERT(CheckProgram("$x = 1; export $x", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(0, errors.Size()); + } + + Y_UNIT_TEST(CompileSqlWithLibsGood) { + TOptions options; + options.IsSql = true; + options.ParseOnly = false; + options.SqlLibs["foo.sql"] = "$x = 1; export $x;"; + TIssues errors; + UNIT_ASSERT(CheckProgram("pragma library('foo.sql');import foo symbols $x; select $x", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(0, errors.Size()); + } + + Y_UNIT_TEST(ParseSqlWithBadLib) { + TOptions options; + options.IsSql = true; + options.ParseOnly = true; + options.SqlLibs["foo.sql"] = "$x = 1; zexport $x;"; + TIssues errors; + UNIT_ASSERT(!CheckProgram("pragma library('foo.sql');import foo symbols $x; select $x", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(1, errors.Size()); + } + + Y_UNIT_TEST(CompileSqlWithUnresolvedLib) { + TOptions options; + options.IsSql = true; + options.ParseOnly = false; + options.SqlLibs["foo.sql"] = "$x = 1; export $x;"; + TIssues errors; + UNIT_ASSERT(!CheckProgram("pragma library('foo.sql');import foo symbols $y; select $y", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(1, errors.Size()); + } + + Y_UNIT_TEST(ParseSqlWithUnresolvedLib) { + TOptions options; + options.IsSql = true; + options.ParseOnly = true; + options.SqlLibs["foo.sql"] = "$x = 1; export $x;"; + TIssues errors; + UNIT_ASSERT(CheckProgram("pragma library('foo.sql');import foo symbols $y; select $y", options, errors)); + UNIT_ASSERT_VALUES_EQUAL(0, errors.Size()); + } +} diff --git a/yql/essentials/public/fastcheck/ut/ya.make b/yql/essentials/public/fastcheck/ut/ya.make new file mode 100644 index 0000000000..858cf8f8ae --- /dev/null +++ b/yql/essentials/public/fastcheck/ut/ya.make @@ -0,0 +1,7 @@ +UNITTEST_FOR(yql/essentials/public/fastcheck) + +SRCS( + fastcheck_ut.cpp +) + +END() diff --git a/yql/essentials/public/fastcheck/ya.make b/yql/essentials/public/fastcheck/ya.make new file mode 100644 index 0000000000..02984ccbdf --- /dev/null +++ b/yql/essentials/public/fastcheck/ya.make @@ -0,0 +1,22 @@ +LIBRARY() + +SRCS( + fastcheck.cpp +) + +PEERDIR( + yql/essentials/ast + yql/essentials/core/services/mounts + yql/essentials/core/user_data + yql/essentials/public/udf/service/exception_policy + yql/essentials/sql + yql/essentials/sql/pg + yql/essentials/parser/pg_wrapper + yql/essentials/providers/common/provider +) + +END() + +RECURSE_FOR_TESTS( + ut +) diff --git a/yql/essentials/public/ya.make b/yql/essentials/public/ya.make index d0c288b427..8cb77bcdb1 100644 --- a/yql/essentials/public/ya.make +++ b/yql/essentials/public/ya.make @@ -1,5 +1,6 @@ RECURSE( decimal + fastcheck issue result_format types |