1414
1515#include < ydb/library/yql/parser/proto_ast/gen/v1_proto_split/SQLv1Parser.pb.main.h>
1616
17+ #include < library/cpp/protobuf/util/simple_reflection.h>
18+ #include < util/generic/algorithm.h>
19+
1720#if defined(_tsan_enabled_)
1821#include < util/system/mutex.h>
1922#endif
@@ -29,18 +32,75 @@ namespace NSQLTranslationV1 {
2932
3033using namespace NSQLv1Generated ;
3134
32- google::protobuf::Message* SqlAST (const TString& query, const TString& queryName, TIssues& err, size_t maxErrors, bool ansiLexer, bool anlr4Parser, google::protobuf::Arena* arena) {
35+ void ValidateMessages (const google::protobuf::Message* msg1, const google::protobuf::Message* msg2, bool & hasNonAscii) {
36+ YQL_ENSURE (!msg1 == !msg2);
37+ if (!msg1) {
38+ return ;
39+ }
40+
41+ YQL_ENSURE (msg1->GetDescriptor () == msg2->GetDescriptor ());
42+ const auto descr = msg1->GetDescriptor ();
43+ if (descr == NSQLv1Generated::TToken::GetDescriptor ()) {
44+ const auto & token1 = dynamic_cast <const NSQLv1Generated::TToken&>(*msg1);
45+ const auto & token2 = dynamic_cast <const NSQLv1Generated::TToken&>(*msg2);
46+ const bool isEof1 = token1.GetId () == Max<ui32>();
47+ const bool isEof2 = token2.GetId () == Max<ui32>();
48+ YQL_ENSURE (isEof1 == isEof2);
49+ YQL_ENSURE (token1.GetValue () == token2.GetValue ());
50+ hasNonAscii = hasNonAscii || AnyOf (token1.GetValue (), [](char c) { return !isascii (c);});
51+ if (!isEof1) {
52+ YQL_ENSURE (token1.GetLine () == token2.GetLine ());
53+ if (!hasNonAscii) {
54+ YQL_ENSURE (token1.GetColumn () == token2.GetColumn ());
55+ }
56+ }
57+
58+ return ;
59+ }
60+
61+ for (int i = 0 ; i < descr->field_count (); ++i) {
62+ const NProtoBuf::FieldDescriptor* fd = descr->field (i);
63+ NProtoBuf::TConstField field1 (*msg1, fd);
64+ NProtoBuf::TConstField field2 (*msg2, fd);
65+ YQL_ENSURE (field1.IsMessage () == field2.IsMessage ());
66+ if (field1.IsMessage ()) {
67+ YQL_ENSURE (field1.Size () == field2.Size ());
68+ for (size_t j = 0 ; j < field1.Size (); ++j) {
69+ ValidateMessages (field1.template Get <NProtoBuf::Message>(j), field2.template Get <NProtoBuf::Message>(j), hasNonAscii);
70+ }
71+ }
72+ }
73+ }
74+
75+ google::protobuf::Message* SqlAST (const TString& query, const TString& queryName, TIssues& err,
76+ size_t maxErrors, bool ansiLexer, bool anlr4Parser, bool testAntlr4, google::protobuf::Arena* arena) {
3377 YQL_ENSURE (arena);
3478#if defined(_tsan_enabled_)
3579 TGuard<TMutex> grd (SanitizerSQLTranslationMutex);
3680#endif
3781 NSQLTranslation::TErrorCollectorOverIssues collector (err, maxErrors, " " );
3882 if (ansiLexer && !anlr4Parser) {
3983 NProtoAST::TProtoASTBuilder<NALPAnsi::SQLv1Parser, NALPAnsi::SQLv1Lexer> builder (query, queryName, arena);
40- return builder.BuildAST (collector);
84+ auto res = builder.BuildAST (collector);
85+ if (testAntlr4) {
86+ NProtoAST::TProtoASTBuilder<NALPAnsiAntlr4::SQLv1Antlr4Parser, NALPAnsiAntlr4::SQLv1Antlr4Lexer> builder (query, queryName, arena);
87+ auto res2 = builder.BuildAST (collector);
88+ bool hasNonAscii = false ;
89+ ValidateMessages (res, res2, hasNonAscii);
90+ }
91+
92+ return res;
4193 } else if (!ansiLexer && !anlr4Parser) {
4294 NProtoAST::TProtoASTBuilder<NALPDefault::SQLv1Parser, NALPDefault::SQLv1Lexer> builder (query, queryName, arena);
43- return builder.BuildAST (collector);
95+ auto res = builder.BuildAST (collector);
96+ if (testAntlr4) {
97+ NProtoAST::TProtoASTBuilder<NALPDefaultAntlr4::SQLv1Antlr4Parser, NALPDefaultAntlr4::SQLv1Antlr4Lexer> builder (query, queryName, arena);
98+ auto res2 = builder.BuildAST (collector);
99+ bool hasNonAscii = false ;
100+ ValidateMessages (res, res2, hasNonAscii);
101+ }
102+
103+ return res;
44104 } else if (ansiLexer && anlr4Parser) {
45105 NProtoAST::TProtoASTBuilder<NALPAnsiAntlr4::SQLv1Antlr4Parser, NALPAnsiAntlr4::SQLv1Antlr4Lexer> builder (query, queryName, arena);
46106 return builder.BuildAST (collector);
@@ -50,17 +110,34 @@ google::protobuf::Message* SqlAST(const TString& query, const TString& queryName
50110 }
51111}
52112
53- google::protobuf::Message* SqlAST (const TString& query, const TString& queryName, NProtoAST::IErrorCollector& err, bool ansiLexer, bool anlr4Parser, google::protobuf::Arena* arena) {
113+ google::protobuf::Message* SqlAST (const TString& query, const TString& queryName, NProtoAST::IErrorCollector& err,
114+ bool ansiLexer, bool anlr4Parser, bool testAntlr4, google::protobuf::Arena* arena) {
54115 YQL_ENSURE (arena);
55116#if defined(_tsan_enabled_)
56117 TGuard<TMutex> grd (SanitizerSQLTranslationMutex);
57118#endif
58119 if (ansiLexer && !anlr4Parser) {
59120 NProtoAST::TProtoASTBuilder<NALPAnsi::SQLv1Parser, NALPAnsi::SQLv1Lexer> builder (query, queryName, arena);
60- return builder.BuildAST (err);
121+ auto res = builder.BuildAST (err);
122+ if (testAntlr4) {
123+ NProtoAST::TProtoASTBuilder<NALPAnsiAntlr4::SQLv1Antlr4Parser, NALPAnsiAntlr4::SQLv1Antlr4Lexer> builder (query, queryName, arena);
124+ auto res2 = builder.BuildAST (err);
125+ bool hasNonAscii = false ;
126+ ValidateMessages (res, res2, hasNonAscii);
127+ }
128+
129+ return res;
61130 } else if (!ansiLexer && !anlr4Parser) {
62131 NProtoAST::TProtoASTBuilder<NALPDefault::SQLv1Parser, NALPDefault::SQLv1Lexer> builder (query, queryName, arena);
63- return builder.BuildAST (err);
132+ auto res = builder.BuildAST (err);
133+ if (testAntlr4) {
134+ NProtoAST::TProtoASTBuilder<NALPDefaultAntlr4::SQLv1Antlr4Parser, NALPDefaultAntlr4::SQLv1Antlr4Lexer> builder (query, queryName, arena);
135+ auto res2 = builder.BuildAST (err);
136+ bool hasNonAscii = false ;
137+ ValidateMessages (res, res2, hasNonAscii);
138+ }
139+
140+ return res;
64141 } else if (ansiLexer && anlr4Parser) {
65142 NProtoAST::TProtoASTBuilder<NALPAnsiAntlr4::SQLv1Antlr4Parser, NALPAnsiAntlr4::SQLv1Antlr4Lexer> builder (query, queryName, arena);
66143 return builder.BuildAST (err);
0 commit comments