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
|
#include "proto_parser.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/lexer/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 <library/cpp/testing/unittest/registar.h>
Y_UNIT_TEST_SUITE(ProtoParserTests) {
google::protobuf::Message* SqlAST(
const TString& query,
NSQLTranslation::TTranslationSettings settings,
NYql::TIssues& issues)
{
NSQLTranslationV1::TLexers lexers;
NSQLTranslationV1::TParsers parsers;
if (!ParseTranslationSettings(query, settings, issues)) {
return nullptr;
}
lexers.Antlr4 = NSQLTranslationV1::MakeAntlr4LexerFactory();
lexers.Antlr4Ansi = NSQLTranslationV1::MakeAntlr4AnsiLexerFactory();
auto lexer = NSQLTranslationV1::MakeLexer(lexers, settings.AnsiLexer);
auto onNextToken = [&](NSQLTranslation::TParsedToken&& token) {
Y_UNUSED(token);
};
if (!lexer->Tokenize(query, "", onNextToken, issues, NSQLTranslation::SQL_MAX_PARSER_ERRORS)) {
return nullptr;
}
parsers.Antlr4 = NSQLTranslationV1::MakeAntlr4ParserFactory(
/*isAmbiguityError=*/false,
/*isAmbiguityDebugging=*/false,
settings.MaxParseTreeDepth);
parsers.Antlr4Ansi = NSQLTranslationV1::MakeAntlr4AnsiParserFactory(
/*isAmbiguityError=*/false,
/*isAmbiguityDebugging=*/false,
settings.MaxParseTreeDepth);
return NSQLTranslationV1::SqlAST(
parsers,
query,
/* queryName = */ "",
issues,
NSQLTranslation::SQL_MAX_PARSER_ERRORS,
settings.AnsiLexer,
settings.Arena);
}
TString GenerateQuery(size_t depth = 8 * 1024) {
const TString prefix = "SELECT 1 FROM (";
const TString core = "SELECT 1";
const TString suffix = ")";
TString query;
query.reserve(prefix.size() * depth + core.size() + suffix.size() * depth);
for (size_t i = 0; i < depth; ++i) {
query += prefix;
}
query += core;
for (size_t i = 0; i < depth; ++i) {
query += suffix;
}
return query;
}
Y_UNIT_TEST(StackOverflowSubquery) {
const auto query = GenerateQuery();
google::protobuf::Arena arena;
NSQLTranslation::TTranslationSettings settings;
settings.Arena = &arena;
settings.MaxParseTreeDepth = 4 * 1024;
NYql::TIssues issues;
const auto* m = SqlAST(query, settings, issues);
UNIT_ASSERT(!m);
UNIT_ASSERT_STRING_CONTAINS(issues.ToOneLineString(), "Maximum parse tree depth exceeded");
}
} // Y_UNIT_TEST_SUITE(ProtoParserTests)
|