summaryrefslogtreecommitdiffstats
path: root/yql/essentials/public/fastcheck/fastcheck.cpp
blob: 3a01f5f6da3f31af3861f1e5878056ebb8377f10 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#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>
#include <yql/essentials/sql/v1/sql.h>
#include <yql/essentials/sql/v1/lexer/antlr4/lexer.h>
#include <yql/essentials/sql/v1/lexer/antlr4_ansi/lexer.h>
#include <yql/essentials/sql/v1/proto_parser/antlr4/proto_parser.h>
#include <yql/essentials/sql/v1/proto_parser/antlr4_ansi/proto_parser.h>
#include <yql/essentials/parser/pg_wrapper/interface/parser.h>
#include <yql/essentials/core/langver/yql_core_langver.h>

namespace NYql {
namespace NFastCheck {

bool CheckProgram(const TString& program, const TOptions& options, TIssues& errors) {
    TMaybe<TIssue> verIssue;
    auto verCheck = CheckLangVersion(options.LangVer, GetMaxReleasedLangVersion(), verIssue);
    if (verIssue) {
        errors.AddIssue(*verIssue);
    }

    if (!verCheck) {
        return false;
    }

    NSQLTranslationV1::TLexers lexers;
    lexers.Antlr4 = NSQLTranslationV1::MakeAntlr4LexerFactory();
    lexers.Antlr4Ansi = NSQLTranslationV1::MakeAntlr4AnsiLexerFactory();
    NSQLTranslationV1::TParsers parsers;
    parsers.Antlr4 = NSQLTranslationV1::MakeAntlr4ParserFactory();
    parsers.Antlr4Ansi = NSQLTranslationV1::MakeAntlr4AnsiParserFactory();

    NSQLTranslation::TTranslators translators(
        nullptr,
        NSQLTranslationV1::MakeTranslator(lexers, parsers),
        NSQLTranslationPG::MakeTranslator()
    );

    TAstParseResult astRes;
    if (options.IsSql) {
        NSQLTranslation::TTranslationSettings settings;
        settings.LangVer = options.LangVer;
        settings.ClusterMapping = options.ClusterMapping;
        settings.SyntaxVersion = options.SyntaxVersion;
        settings.V0Behavior = NSQLTranslation::EV0Behavior::Disable;
        settings.EmitReadsForExists = true;
        if (options.IsLibrary) {
            settings.Mode = NSQLTranslation::ESqlMode::LIBRARY;
        }

        astRes = SqlToYql(translators, program, settings);
    } else {
        astRes = ParseAst(program);
    }

    if (!astRes.IsOk()) {
        errors.AddIssues(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.LangVer = options.LangVer;
            settings.ClusterMapping = options.ClusterMapping;
            settings.SyntaxVersion = options.SyntaxVersion;
            settings.V0Behavior = NSQLTranslation::EV0Behavior::Disable;
            settings.File = x.first;
            settings.Mode = NSQLTranslation::ESqlMode::LIBRARY;

            astRes = SqlToYql(translators, x.second, settings);
            if (!astRes.IsOk()) {
                errors.AddIssues(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.AddIssues(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.AddIssues(exprCtx.IssueManager.GetIssues());
        exprCtx.IssueManager.Reset();
        return false;
    }

    return true;
}

}
}