yql_facade_run.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. #include "yql_facade_run.h"
  2. #include <yql/essentials/providers/pg/provider/yql_pg_provider.h>
  3. #include <yql/essentials/providers/common/provider/yql_provider_names.h>
  4. #include <yql/essentials/providers/common/proto/gateways_config.pb.h>
  5. #include <yql/essentials/providers/common/udf_resolve/yql_outproc_udf_resolver.h>
  6. #include <yql/essentials/providers/common/udf_resolve/yql_simple_udf_resolver.h>
  7. #include <yql/essentials/providers/common/udf_resolve/yql_udf_resolver_with_index.h>
  8. #include <yql/essentials/core/yql_user_data_storage.h>
  9. #include <yql/essentials/core/yql_udf_resolver.h>
  10. #include <yql/essentials/core/yql_udf_index.h>
  11. #include <yql/essentials/core/yql_udf_index_package_set.h>
  12. #include <yql/essentials/core/yql_library_compiler.h>
  13. #include <yql/essentials/core/yql_type_annotation.h>
  14. #include <yql/essentials/core/pg_ext/yql_pg_ext.h>
  15. #include <yql/essentials/core/services/mounts/yql_mounts.h>
  16. #include <yql/essentials/core/services/yql_out_transformers.h>
  17. #include <yql/essentials/core/file_storage/file_storage.h>
  18. #include <yql/essentials/core/file_storage/proto/file_storage.pb.h>
  19. #include <yql/essentials/core/peephole_opt/yql_opt_peephole_physical.h>
  20. #include <yql/essentials/core/facade/yql_facade.h>
  21. #include <yql/essentials/core/url_lister/url_lister_manager.h>
  22. #include <yql/essentials/core/url_preprocessing/url_preprocessing.h>
  23. #include <yql/essentials/core/qplayer/storage/file/yql_qstorage_file.h>
  24. #include <yql/essentials/minikql/invoke_builtins/mkql_builtins.h>
  25. #include <yql/essentials/minikql/mkql_function_registry.h>
  26. #include <yql/essentials/ast/yql_expr.h>
  27. #include <yql/essentials/parser/pg_wrapper/interface/parser.h>
  28. #include <yql/essentials/parser/pg_catalog/catalog.h>
  29. #include <yql/essentials/public/udf/udf_version.h>
  30. #include <yql/essentials/public/udf/udf_registrator.h>
  31. #include <yql/essentials/public/udf/udf_validate.h>
  32. #include <yql/essentials/public/result_format/yql_result_format_response.h>
  33. #include <yql/essentials/public/result_format/yql_result_format_type.h>
  34. #include <yql/essentials/public/result_format/yql_result_format_data.h>
  35. #include <yql/essentials/utils/failure_injector/failure_injector.h>
  36. #include <yql/essentials/utils/backtrace/backtrace.h>
  37. #include <yql/essentials/utils/log/log.h>
  38. #include <yql/essentials/protos/yql_mount.pb.h>
  39. #include <yql/essentials/protos/pg_ext.pb.h>
  40. #include <yql/essentials/sql/settings/translation_settings.h>
  41. #include <yql/essentials/sql/v1/format/sql_format.h>
  42. #include <library/cpp/resource/resource.h>
  43. #include <library/cpp/yson/node/node_io.h>
  44. #include <library/cpp/yson/writer.h>
  45. #include <google/protobuf/text_format.h>
  46. #include <google/protobuf/arena.h>
  47. #include <util/stream/output.h>
  48. #include <util/stream/file.h>
  49. #include <util/stream/null.h>
  50. #include <util/system/user.h>
  51. #include <util/system/env.h>
  52. #include <util/string/split.h>
  53. #include <util/string/join.h>
  54. #include <util/string/builder.h>
  55. #include <util/string/strip.h>
  56. #include <util/generic/vector.h>
  57. #include <util/generic/ptr.h>
  58. #include <util/generic/yexception.h>
  59. #include <util/datetime/base.h>
  60. #ifdef __unix__
  61. #include <sys/resource.h>
  62. #endif
  63. namespace {
  64. const ui32 PRETTY_FLAGS = NYql::TAstPrintFlags::PerLine | NYql::TAstPrintFlags::ShortQuote |
  65. NYql::TAstPrintFlags::AdaptArbitraryContent;
  66. template <typename TMessage>
  67. THolder<TMessage> ParseProtoConfig(const TString& cfgFile) {
  68. auto config = MakeHolder<TMessage>();
  69. TString configData = TFileInput(cfgFile).ReadAll();
  70. using ::google::protobuf::TextFormat;
  71. if (!TextFormat::ParseFromString(configData, config.Get())) {
  72. throw yexception() << "Bad format of config file " << cfgFile;
  73. }
  74. return config;
  75. }
  76. template <typename TMessage>
  77. THolder<TMessage> ParseProtoFromResource(TStringBuf resourceName) {
  78. if (!NResource::Has(resourceName)) {
  79. return {};
  80. }
  81. auto config = MakeHolder<TMessage>();
  82. TString configData = NResource::Find(resourceName);
  83. using ::google::protobuf::TextFormat;
  84. if (!TextFormat::ParseFromString(configData, config.Get())) {
  85. throw yexception() << "Bad format of config " << resourceName;
  86. }
  87. return config;
  88. }
  89. class TOptPipelineConfigurator : public NYql::IPipelineConfigurator {
  90. public:
  91. TOptPipelineConfigurator(NYql::TProgramPtr prg, IOutputStream* planStream, IOutputStream* exprStream, bool withTypes)
  92. : Program_(std::move(prg))
  93. , PlanStream_(planStream)
  94. , ExprStream_(exprStream)
  95. , WithTypes_(withTypes)
  96. {
  97. }
  98. void AfterCreate(NYql::TTransformationPipeline* pipeline) const final {
  99. Y_UNUSED(pipeline);
  100. }
  101. void AfterTypeAnnotation(NYql::TTransformationPipeline* pipeline) const final {
  102. pipeline->Add(NYql::TExprLogTransformer::Sync("OptimizedExpr", NYql::NLog::EComponent::Core, NYql::NLog::ELevel::TRACE),
  103. "OptTrace", NYql::TIssuesIds::CORE, "OptTrace");
  104. }
  105. void AfterOptimize(NYql::TTransformationPipeline* pipeline) const final {
  106. if (ExprStream_) {
  107. pipeline->Add(NYql::TExprOutputTransformer::Sync(Program_->ExprRoot(), ExprStream_, WithTypes_), "AstOutput");
  108. }
  109. if (PlanStream_) {
  110. pipeline->Add(NYql::TPlanOutputTransformer::Sync(PlanStream_, Program_->GetPlanBuilder(), Program_->GetOutputFormat()), "PlanOutput");
  111. }
  112. }
  113. private:
  114. NYql::TProgramPtr Program_;
  115. IOutputStream* PlanStream_;
  116. IOutputStream* ExprStream_;
  117. bool WithTypes_;
  118. };
  119. class TPeepHolePipelineConfigurator : public NYql::IPipelineConfigurator {
  120. public:
  121. TPeepHolePipelineConfigurator() {
  122. }
  123. void AfterCreate(NYql::TTransformationPipeline* pipeline) const final {
  124. Y_UNUSED(pipeline);
  125. }
  126. void AfterTypeAnnotation(NYql::TTransformationPipeline* pipeline) const final {
  127. pipeline->Add(NYql::TExprLogTransformer::Sync("OptimizedExpr", NYql::NLog::EComponent::Core, NYql::NLog::ELevel::TRACE),
  128. "OptTrace", NYql::TIssuesIds::CORE, "OptTrace");
  129. }
  130. void AfterOptimize(NYql::TTransformationPipeline* pipeline) const final {
  131. pipeline->Add(NYql::MakePeepholeOptimization(pipeline->GetTypeAnnotationContext()), "PeepHole");
  132. }
  133. };
  134. } // unnamed
  135. namespace NYql {
  136. TFacadeRunOptions::TFacadeRunOptions() {
  137. }
  138. TFacadeRunOptions::~TFacadeRunOptions() {
  139. }
  140. void TFacadeRunOptions::InitLogger() {
  141. if (Verbosity != LOG_DEF_PRIORITY || ShowLog) {
  142. NLog::ELevel level = NLog::ELevelHelpers::FromInt(Verbosity);
  143. if (ShowLog) {
  144. level = Max(level, NLog::ELevel::DEBUG);
  145. }
  146. NLog::EComponentHelpers::ForEach([level](NLog::EComponent c) {
  147. NYql::NLog::YqlLogger().SetComponentLevel(c, level);
  148. });
  149. }
  150. if (TraceOptStream) {
  151. NLog::YqlLogger().SetComponentLevel(NLog::EComponent::Core, NLog::ELevel::TRACE);
  152. NLog::YqlLogger().SetComponentLevel(NLog::EComponent::CoreEval, NLog::ELevel::TRACE);
  153. NLog::YqlLogger().SetComponentLevel(NLog::EComponent::CorePeepHole, NLog::ELevel::TRACE);
  154. }
  155. }
  156. void TFacadeRunOptions::PrintInfo(const TString& msg) {
  157. if (!NoDebug && Verbosity >= TLOG_INFO) {
  158. Cerr << msg << Endl;
  159. }
  160. }
  161. void TFacadeRunOptions::Parse(int argc, const char *argv[]) {
  162. User = GetUsername();
  163. if (EnableCredentials) {
  164. Token = GetEnv("YQL_TOKEN");
  165. if (!Token) {
  166. const TString home = GetEnv("HOME");
  167. auto tokenPath = TFsPath(home) / ".yql" / "token";
  168. if (tokenPath.Exists()) {
  169. Token = StripStringRight(TFileInput(tokenPath).ReadAll());
  170. }
  171. }
  172. }
  173. NLastGetopt::TOpts opts = NLastGetopt::TOpts::Default();
  174. opts.AddHelpOption();
  175. opts.AddLongOption('p', "program", "Program file (use - to read from stdin)").Required().RequiredArgument("FILE")
  176. .Handler1T<TString>([this](const TString& file) {
  177. ProgramFile = file;
  178. if (ProgramFile == "-") {
  179. ProgramFile = "-stdin-";
  180. ProgramText = Cin.ReadAll();
  181. } else {
  182. ProgramText = TFileInput(ProgramFile).ReadAll();
  183. }
  184. User = GetUsername();
  185. });
  186. opts.AddLongOption('s', "sql", "Program is SQL query").NoArgument().StoreValue(&ProgramType, EProgramType::Sql);
  187. if (PgSupport) {
  188. opts.AddLongOption("pg", "Program has PG syntax").NoArgument().StoreValue(&ProgramType, EProgramType::Pg);
  189. opts.AddLongOption("pg-ext", "Pg extensions config file").Optional().RequiredArgument("FILE")
  190. .Handler1T<TString>([this](const TString& file) {
  191. PgExtConfig = ParseProtoConfig<NProto::TPgExtensions>(file);
  192. });
  193. }
  194. opts.AddLongOption('f', "file", "Additional files").RequiredArgument("name@path")
  195. .KVHandler([this](TString name, TString path) {
  196. if (name.empty() || path.empty()) {
  197. throw yexception() << "Incorrect file mapping, expected form name@path, e.g. MyFile@file.txt";
  198. }
  199. auto& entry = DataTable[NYql::TUserDataKey::File(NYql::GetDefaultFilePrefix() + name)];
  200. entry.Type = NYql::EUserDataType::PATH;
  201. entry.Data = path;
  202. }, '@');
  203. opts.AddLongOption('U', "url", "Additional urls").RequiredArgument("name@path")
  204. .KVHandler([this](TString name, TString url) {
  205. if (name.empty() || url.empty()) {
  206. throw yexception() << "url mapping, expected form name@url, e.g. MyUrl@http://example.com/file";
  207. }
  208. auto& entry = DataTable[NYql::TUserDataKey::File(NYql::GetDefaultFilePrefix() + name)];
  209. entry.Type = NYql::EUserDataType::URL;
  210. entry.Data = url;
  211. }, '@');
  212. opts.AddLongOption('m', "mounts", "Mount points config file.").Optional().RequiredArgument("FILE")
  213. .Handler1T<TString>([this](const TString& file) {
  214. MountConfig = ParseProtoConfig<NYqlMountConfig::TMountConfig>(file);
  215. });
  216. opts.AddLongOption("params-file", "Query parameters values in YSON format").Optional().RequiredArgument("FILE")
  217. .Handler1T<TString>([this](const TString& file) {
  218. Params = TFileInput(file).ReadAll();
  219. });
  220. opts.AddLongOption('G', "gateways", TStringBuilder() << "Used gateways, available: " << JoinSeq(",", SupportedGateways_)).DefaultValue(JoinSeq(",", GatewayTypes))
  221. .Handler1T<TString>([this](const TString& gateways) {
  222. ::StringSplitter(gateways).Split(',').Consume([&](const TStringBuf& val) {
  223. if (!SupportedGateways_.contains(val)) {
  224. throw yexception() << "Unsupported gateway \"" << val << '"';
  225. }
  226. GatewayTypes.emplace(val);
  227. });
  228. });
  229. opts.AddLongOption("gateways-cfg", "Gateways configuration file").Optional().RequiredArgument("FILE")
  230. .Handler1T<TString>([this](const TString& file) {
  231. GatewaysConfig = ParseProtoConfig<TGatewaysConfig>(file);
  232. });
  233. opts.AddLongOption("fs-cfg", "Fs configuration file").Optional().RequiredArgument("FILE")
  234. .Handler1T<TString>([this](const TString& file) {
  235. FsConfig = MakeHolder<TFileStorageConfig>();
  236. LoadFsConfigFromFile(file, *FsConfig);
  237. });
  238. opts.AddLongOption('u', "udf", "Load shared library with UDF by given path").RequiredArgument("PATH").AppendTo(&UdfsPaths);
  239. opts.AddLongOption("udfs-dir", "Load all shared libraries with UDFs found in given directory").RequiredArgument("DIR")
  240. .Handler1T<TString>([this](const TString& dir) {
  241. NKikimr::NMiniKQL::FindUdfsInDir(dir, &UdfsPaths);
  242. });
  243. opts.AddLongOption("udf-resolver", "Path to udf-resolver").Optional().RequiredArgument("PATH").StoreResult(&UdfResolverPath);
  244. opts.AddLongOption("udf-resolver-filter-syscalls", "Filter syscalls in udf resolver").Optional().NoArgument().SetFlag(&UdfResolverFilterSyscalls);
  245. opts.AddLongOption("scan-udfs", "Scan specified udfs with external udf-resolver to use static function registry").NoArgument().SetFlag(&ScanUdfs);
  246. opts.AddLongOption("parse-only", "Parse program and exit").NoArgument().StoreValue(&Mode, ERunMode::Parse);
  247. opts.AddLongOption("compile-only", "Compiled program and exit").NoArgument().StoreValue(&Mode, ERunMode::Compile);
  248. opts.AddLongOption("validate", "Validate program and exit").NoArgument().StoreValue(&Mode, ERunMode::Validate);
  249. opts.AddLongOption("lineage", "Calculate program lineage and exit").NoArgument().StoreValue(&Mode, ERunMode::Lineage);
  250. opts.AddLongOption('O',"optimize", "Optimize program and exir").NoArgument().StoreValue(&Mode, ERunMode::Optimize);
  251. opts.AddLongOption('D', "discover", "Discover tables in the program and exit").NoArgument().StoreValue(&Mode, ERunMode::Discover);
  252. opts.AddLongOption("peephole", "Perform peephole program optimization and exit").NoArgument().StoreValue(&Mode, ERunMode::Peephole);
  253. opts.AddLongOption('R',"run", "Run progrum (use by default)").NoArgument().StoreValue(&Mode, ERunMode::Run);
  254. opts.AddLongOption('L', "show-log", "Show transformation log").Optional().NoArgument().SetFlag(&ShowLog);
  255. opts.AddLongOption('v', "verbosity", "Log verbosity level").Optional().RequiredArgument("LEVEL").StoreResult(&Verbosity);
  256. opts.AddLongOption("print-ast", "Print AST after loading").NoArgument().SetFlag(&PrintAst);
  257. opts.AddLongOption("print-expr", "Print rebuild AST before execution").NoArgument()
  258. .Handler0([this]() {
  259. if (!ExprStream) {
  260. ExprStream = &Cout;
  261. }
  262. });
  263. opts.AddLongOption("with-types", "Print types annotation").NoArgument().SetFlag(&WithTypes);
  264. opts.AddLongOption("trace-opt", "Print AST in the begin of each transformation").NoArgument()
  265. .Handler0([this]() {
  266. TraceOptStream = &Cerr;
  267. });
  268. opts.AddLongOption("expr-file", "Print AST to that file instead of stdout").Optional().RequiredArgument("FILE")
  269. .Handler1T<TString>([this](const TString& file) {
  270. ExprStreamHolder_ = MakeHolder<TFixedBufferFileOutput>(file);
  271. ExprStream = ExprStreamHolder_.Get();
  272. });
  273. opts.AddLongOption("print-result", "Print program execution result to stdout").NoArgument()
  274. .Handler0([this]() {
  275. if (!ResultStream) {
  276. ResultStream = &Cout;
  277. }
  278. });
  279. opts.AddLongOption("format", "Results format")
  280. .Optional()
  281. .RequiredArgument("STR")
  282. .Choices(THashSet<TString>{"text", "binary", "pretty"})
  283. .Handler1T<TString>([this](const TString& val) {
  284. if (val == "text") {
  285. ResultsFormat = NYson::EYsonFormat::Text;
  286. } else if (val == "binary") {
  287. ResultsFormat = NYson::EYsonFormat::Binary;
  288. } else if (val == "pretty") {
  289. ResultsFormat = NYson::EYsonFormat::Pretty;
  290. } else {
  291. throw yexception() << "Unknown result format " << val;
  292. }
  293. });
  294. opts.AddLongOption("result-file", "Print program execution result to file").Optional().RequiredArgument("FILE")
  295. .Handler1T<TString>([this](const TString& file) {
  296. ResultStreamHolder_ = MakeHolder<TFixedBufferFileOutput>(file);
  297. ResultStream = ResultStreamHolder_.Get();
  298. });
  299. opts.AddLongOption('P',"trace-plan", "Print plan before execution").NoArgument()
  300. .Handler0([this]() {
  301. if (!PlanStream) {
  302. PlanStream = &Cerr;
  303. }
  304. });
  305. opts.AddLongOption("plan-file", "Print program plan to file").Optional().RequiredArgument("FILE")
  306. .Handler1T<TString>([this](const TString& file) {
  307. PlanStreamHolder_ = MakeHolder<TFixedBufferFileOutput>(file);
  308. PlanStream = PlanStreamHolder_.Get();
  309. });
  310. opts.AddLongOption("err-file", "Print validate/optimize/runtime errors to file")
  311. .Handler1T<TString>([this](const TString& file) {
  312. ErrStreamHolder_ = MakeHolder<TFixedBufferFileOutput>(file);
  313. ErrStream = ErrStreamHolder_.Get();
  314. });
  315. opts.AddLongOption("full-expr", "Avoid buffering of expr/plan").NoArgument().SetFlag(&FullExpr);
  316. opts.AddLongOption("mem-limit", "Set memory limit in megabytes")
  317. .Handler1T<ui32>(0, [](ui32 memLimit) {
  318. if (memLimit) {
  319. #ifdef __unix__
  320. auto memLimitBytes = memLimit * 1024 * 1024;
  321. struct rlimit rl;
  322. if (getrlimit(RLIMIT_AS, &rl)) {
  323. throw TSystemError() << "Cannot getrlimit(RLIMIT_AS)";
  324. }
  325. rl.rlim_cur = memLimitBytes;
  326. if (setrlimit(RLIMIT_AS, &rl)) {
  327. throw TSystemError() << "Cannot setrlimit(RLIMIT_AS) to " << memLimitBytes << " bytes";
  328. }
  329. #else
  330. throw yexception() << "Memory limit can not be set on this platfrom";
  331. #endif
  332. }
  333. });
  334. opts.AddLongOption("validate-mode", "Validate udf mode, available values: " + NUdf::ValidateModeAvailables())
  335. .DefaultValue(NUdf::ValidateModeAsStr(NUdf::EValidateMode::Greedy))
  336. .Handler1T<TString>([this](const TString& mode) {
  337. ValidateMode = NUdf::ValidateModeByStr(mode);
  338. });
  339. opts.AddLongOption("stat", "Print execution statistics").Optional().OptionalArgument("FILE")
  340. .Handler1T<TString>([this](const TString& file) {
  341. if (file) {
  342. StatStreamHolder_ = MakeHolder<TFileOutput>(file);
  343. StatStream = StatStreamHolder_.Get();
  344. } else {
  345. StatStream = &Cerr;
  346. }
  347. });
  348. opts.AddLongOption("full-stat", "Output full execution statistics").Optional().NoArgument().SetFlag(&FullStatistics);
  349. opts.AddLongOption("sql-flags", "SQL translator pragma flags").SplitHandler(&SqlFlags, ',');
  350. opts.AddLongOption("syntax-version", "SQL syntax version").StoreResult(&SyntaxVersion).DefaultValue(1);
  351. opts.AddLongOption("ansi-lexer", "Use ansi lexer").NoArgument().SetFlag(&AnsiLexer);
  352. opts.AddLongOption("assume-ydb-on-slash", "Assume YDB provider if cluster name starts with '/'").NoArgument().SetFlag(&AssumeYdbOnClusterWithSlash);
  353. opts.AddLongOption("test-antlr4", "Check antlr4 parser").NoArgument().SetFlag(&TestAntlr4);
  354. opts.AddLongOption("with-final-issues", "Include some final messages (like statistic) in issues").NoArgument().SetFlag(&WithFinalIssues);
  355. if (FailureInjectionSupport) {
  356. opts.AddLongOption("failure-inject", "Activate failure injection")
  357. .Optional()
  358. .RequiredArgument("INJECTION_NAME=FAIL_COUNT or INJECTION_NAME=SKIP_COUNT/FAIL_COUNT")
  359. .KVHandler([](TString name, TString value) {
  360. TFailureInjector::Activate();
  361. TStringBuf fail = value;
  362. TStringBuf skip;
  363. if (TStringBuf(value).TrySplit('/', skip, fail)) {
  364. TFailureInjector::Set(name, FromString<ui32>(skip), FromString<ui32>(fail));
  365. } else {
  366. TFailureInjector::Set(name, 0, FromString<ui32>(fail));
  367. }
  368. });
  369. }
  370. if (EnableCredentials) {
  371. opts.AddLongOption("token", "YQL token")
  372. .Optional()
  373. .RequiredArgument("VALUE")
  374. .StoreResult(&Token);
  375. opts.AddLongOption("custom-tokens", "Custom tokens")
  376. .Optional()
  377. .RequiredArgument("NAME=VALUE or NAME=@PATH")
  378. .KVHandler([this](TString key, TString value) {
  379. if (value.StartsWith('@')) {
  380. value = StripStringRight(TFileInput(value.substr(1)).ReadAll());
  381. }
  382. Credentials->AddCredential(key, TCredential("custom", "", value));
  383. });
  384. }
  385. if (EnableQPlayer) {
  386. opts.AddLongOption("qstorage-dir", "Directory for QStorage").RequiredArgument("DIR")
  387. .Handler1T<TString>([this](const TString& dir) {
  388. QPlayerStorage_ = MakeFileQStorage(dir);
  389. });
  390. opts.AddLongOption("op-id", "QStorage operation id").StoreResult(&OperationId).DefaultValue("dummy_op");
  391. opts.AddLongOption("capture", "Write query metadata to QStorage").NoArgument()
  392. .Handler0([this]() {
  393. if (EQPlayerMode::Replay == QPlayerMode) {
  394. throw yexception() << "replay and capture options can't be used simultaneously";
  395. }
  396. QPlayerMode = EQPlayerMode::Capture;
  397. });
  398. opts.AddLongOption("replay", "Read query metadata from QStorage").NoArgument()
  399. .Handler0([this]() {
  400. if (EQPlayerMode::Capture == QPlayerMode) {
  401. throw yexception() << "replay and capture options can't be used simultaneously";
  402. }
  403. QPlayerMode = EQPlayerMode::Replay;
  404. });
  405. }
  406. opts.SetFreeArgsMax(0);
  407. for (auto& ext: OptExtenders_) {
  408. ext(opts);
  409. }
  410. auto res = NLastGetopt::TOptsParseResult(&opts, argc, argv);
  411. if (QPlayerMode != EQPlayerMode::None) {
  412. if (!QPlayerStorage_) {
  413. QPlayerStorage_ = MakeFileQStorage(".");
  414. }
  415. if (EQPlayerMode::Replay == QPlayerMode) {
  416. QPlayerContext = TQContext(QPlayerStorage_->MakeReader(OperationId, {}));
  417. ProgramFile = "-replay-";
  418. ProgramText = "";
  419. } else if (EQPlayerMode::Capture == QPlayerMode) {
  420. QPlayerContext = TQContext(QPlayerStorage_->MakeWriter(OperationId, {}));
  421. }
  422. }
  423. if (Mode >= ERunMode::Validate && GatewayTypes.empty()) {
  424. throw yexception() << "At least one gateway from the list " << JoinSeq(",", SupportedGateways_).Quote() << " must be specified";
  425. }
  426. if (!GatewaysConfig) {
  427. GatewaysConfig = ParseProtoFromResource<TGatewaysConfig>("gateways.conf");
  428. }
  429. if (GatewaysConfig && GatewaysConfig->HasSqlCore()) {
  430. SqlFlags.insert(GatewaysConfig->GetSqlCore().GetTranslationFlags().begin(), GatewaysConfig->GetSqlCore().GetTranslationFlags().end());
  431. }
  432. UpdateSqlFlagsFromQContext(QPlayerContext, SqlFlags);
  433. if (!FsConfig) {
  434. FsConfig = MakeHolder<TFileStorageConfig>();
  435. if (NResource::Has("fs.conf")) {
  436. LoadFsConfigFromResource("fs.conf", *FsConfig);
  437. }
  438. }
  439. if (EnableCredentials && Token) {
  440. for (auto name: SupportedGateways_) {
  441. Credentials->AddCredential(TStringBuilder() << "default_" << name, TCredential(name, "", Token));
  442. }
  443. }
  444. for (auto& handle: OptHandlers_) {
  445. handle(res);
  446. }
  447. }
  448. TFacadeRunner::TFacadeRunner(TString name)
  449. : Name_(std::move(name))
  450. {
  451. }
  452. TFacadeRunner::~TFacadeRunner() {
  453. }
  454. TIntrusivePtr<NKikimr::NMiniKQL::IFunctionRegistry> TFacadeRunner::GetFuncRegistry() {
  455. return FuncRegistry_;
  456. }
  457. int TFacadeRunner::Main(int argc, const char *argv[]) {
  458. NYql::NBacktrace::RegisterKikimrFatalActions();
  459. NYql::NBacktrace::EnableKikimrSymbolize();
  460. NYql::NLog::YqlLoggerScope logger(&Cerr);
  461. try {
  462. return DoMain(argc, argv);
  463. }
  464. catch (...) {
  465. Cerr << CurrentExceptionMessage() << Endl;
  466. return 1;
  467. }
  468. }
  469. int TFacadeRunner::DoMain(int argc, const char *argv[]) {
  470. Y_UNUSED(NUdf::GetStaticSymbols());
  471. RunOptions_.Parse(argc, argv);
  472. if (!RunOptions_.NoDebug) {
  473. Cerr << Name_ << " ABI version: " << NKikimr::NUdf::CurrentAbiVersionStr() << Endl;
  474. }
  475. RunOptions_.InitLogger();
  476. if (RunOptions_.PgSupport) {
  477. ClusterMapping_["pg_catalog"] = PgProviderName;
  478. ClusterMapping_["information_schema"] = PgProviderName;
  479. NPg::SetSqlLanguageParser(NSQLTranslationPG::CreateSqlLanguageParser());
  480. NPg::LoadSystemFunctions(*NSQLTranslationPG::CreateSystemFunctionsParser());
  481. if (RunOptions_.PgExtConfig) {
  482. TVector<NPg::TExtensionDesc> extensions;
  483. PgExtensionsFromProto(*RunOptions_.PgExtConfig, extensions);
  484. NPg::RegisterExtensions(extensions, RunOptions_.QPlayerContext.CanRead(),
  485. *NSQLTranslationPG::CreateExtensionSqlParser(),
  486. NKikimr::NMiniKQL::CreateExtensionLoader().get());
  487. }
  488. NPg::GetSqlLanguageParser()->Freeze();
  489. }
  490. FuncRegistry_ = NKikimr::NMiniKQL::CreateFunctionRegistry(&NYql::NBacktrace::KikimrBackTrace,
  491. NKikimr::NMiniKQL::CreateBuiltinRegistry(), true, RunOptions_.UdfsPaths);
  492. TExprContext ctx;
  493. if (RunOptions_.PgSupport) {
  494. ctx.NextUniqueId = NPg::GetSqlLanguageParser()->GetContext().NextUniqueId;
  495. }
  496. IModuleResolver::TPtr moduleResolver;
  497. if (RunOptions_.MountConfig) {
  498. TModulesTable modules;
  499. FillUserDataTableFromFileSystem(*RunOptions_.MountConfig, RunOptions_.DataTable);
  500. if (!CompileLibraries(RunOptions_.DataTable, ctx, modules, RunOptions_.OptimizeLibs && RunOptions_.Mode >= ERunMode::Validate)) {
  501. *RunOptions_.ErrStream << "Errors on compile libraries:" << Endl;
  502. ctx.IssueManager.GetIssues().PrintTo(*RunOptions_.ErrStream);
  503. return -1;
  504. }
  505. moduleResolver = std::make_shared<TModuleResolver>(std::move(modules), ctx.NextUniqueId, ClusterMapping_, RunOptions_.SqlFlags, RunOptions_.Mode >= ERunMode::Validate);
  506. } else {
  507. if (!GetYqlDefaultModuleResolver(ctx, moduleResolver, ClusterMapping_, RunOptions_.OptimizeLibs && RunOptions_.Mode >= ERunMode::Validate)) {
  508. *RunOptions_.ErrStream << "Errors loading default YQL libraries:" << Endl;
  509. ctx.IssueManager.GetIssues().PrintTo(*RunOptions_.ErrStream);
  510. return -1;
  511. }
  512. }
  513. TExprContext::TFreezeGuard freezeGuard(ctx);
  514. if (RunOptions_.Mode >= ERunMode::Validate) {
  515. std::vector<NFS::IDownloaderPtr> downloaders;
  516. for (auto& factory: FsDownloadFactories_) {
  517. if (auto download = factory()) {
  518. downloaders.push_back(std::move(download));
  519. }
  520. }
  521. FileStorage_ = WithAsync(CreateFileStorage(*RunOptions_.FsConfig, downloaders));
  522. }
  523. IUdfResolver::TPtr udfResolver;
  524. TUdfIndex::TPtr udfIndex;
  525. if (FileStorage_ && RunOptions_.ScanUdfs) {
  526. if (!RunOptions_.UdfResolverPath) {
  527. Cerr << "udf-resolver path must be specified when use 'scan-udfs'";
  528. return -1;
  529. }
  530. udfResolver = NCommon::CreateOutProcUdfResolver(FuncRegistry_.Get(), FileStorage_, RunOptions_.UdfResolverPath, {}, {}, RunOptions_.UdfResolverFilterSyscalls, {});
  531. RunOptions_.PrintInfo(TStringBuilder() << TInstant::Now().ToStringLocalUpToSeconds() << " Udf scanning started for " << RunOptions_.UdfsPaths.size() << " udfs ...");
  532. udfIndex = new TUdfIndex();
  533. LoadRichMetadataToUdfIndex(*udfResolver, RunOptions_.UdfsPaths, false, TUdfIndex::EOverrideMode::RaiseError, *udfIndex);
  534. RunOptions_.PrintInfo(TStringBuilder() << TInstant::Now().ToStringLocalUpToSeconds() << " UdfIndex done.");
  535. udfResolver = NCommon::CreateUdfResolverWithIndex(udfIndex, udfResolver, FileStorage_);
  536. RunOptions_.PrintInfo(TStringBuilder() << TInstant::Now().ToStringLocalUpToSeconds() << " Udfs scanned");
  537. } else {
  538. udfResolver = FileStorage_ && RunOptions_.UdfResolverPath
  539. ? NCommon::CreateOutProcUdfResolver(FuncRegistry_.Get(), FileStorage_, RunOptions_.UdfResolverPath, {}, {}, RunOptions_.UdfResolverFilterSyscalls, {})
  540. : NCommon::CreateSimpleUdfResolver(FuncRegistry_.Get(), FileStorage_, true);
  541. }
  542. TVector<TDataProviderInitializer> dataProvidersInit;
  543. if (RunOptions_.PgSupport) {
  544. dataProvidersInit.push_back(GetPgDataProviderInitializer());
  545. }
  546. for (auto& factory: ProviderFactories_) {
  547. if (auto init = factory()) {
  548. dataProvidersInit.push_back(std::move(init));
  549. }
  550. }
  551. TVector<IUrlListerPtr> urlListers;
  552. for (auto& factory: UrlListerFactories_) {
  553. if (auto listener = factory()) {
  554. urlListers.push_back(std::move(listener));
  555. }
  556. }
  557. TProgramFactory factory(RunOptions_.UseRepeatableRandomAndTimeProviders, FuncRegistry_.Get(), ctx.NextUniqueId, dataProvidersInit, Name_);
  558. factory.AddUserDataTable(RunOptions_.DataTable);
  559. factory.SetModules(moduleResolver);
  560. factory.SetFileStorage(FileStorage_);
  561. if (RunOptions_.GatewaysConfig && RunOptions_.GatewaysConfig->HasFs()) {
  562. factory.SetUrlPreprocessing(new NYql::TUrlPreprocessing(*RunOptions_.GatewaysConfig));
  563. }
  564. factory.SetUdfIndex(udfIndex, new TUdfIndexPackageSet());
  565. factory.SetUdfResolver(udfResolver);
  566. factory.SetGatewaysConfig(RunOptions_.GatewaysConfig.Get());
  567. factory.SetCredentials(RunOptions_.Credentials);
  568. factory.EnableRangeComputeFor();
  569. if (!urlListers.empty()) {
  570. factory.SetUrlListerManager(MakeUrlListerManager(urlListers));
  571. }
  572. int result = DoRun(factory);
  573. if (result == 0 && EQPlayerMode::Capture == RunOptions_.QPlayerMode) {
  574. RunOptions_.QPlayerContext.GetWriter()->Commit().GetValueSync();
  575. }
  576. return result;
  577. }
  578. int TFacadeRunner::DoRun(TProgramFactory& factory) {
  579. TProgramPtr program = factory.Create(RunOptions_.ProgramFile, RunOptions_.ProgramText, RunOptions_.OperationId, EHiddenMode::Disable, RunOptions_.QPlayerContext);;
  580. if (RunOptions_.Params) {
  581. program->SetParametersYson(RunOptions_.Params);
  582. }
  583. if (RunOptions_.EnableResultPosition) {
  584. program->EnableResultPosition();
  585. }
  586. if (ProgressWriter_) {
  587. program->SetProgressWriter(ProgressWriter_);
  588. }
  589. program->SetUseTableMetaFromGraph(RunOptions_.UseMetaFromGrpah);
  590. program->SetValidateOptions(RunOptions_.ValidateMode);
  591. bool fail = false;
  592. if (RunOptions_.ProgramType != EProgramType::SExpr) {
  593. RunOptions_.PrintInfo("Parse SQL...");
  594. google::protobuf::Arena arena;
  595. NSQLTranslation::TTranslationSettings settings;
  596. settings.Arena = &arena;
  597. settings.PgParser = EProgramType::Pg == RunOptions_.ProgramType;
  598. settings.ClusterMapping = ClusterMapping_;
  599. settings.Flags = RunOptions_.SqlFlags;
  600. settings.SyntaxVersion = RunOptions_.SyntaxVersion;
  601. settings.AnsiLexer = RunOptions_.AnsiLexer;
  602. settings.TestAntlr4 = RunOptions_.TestAntlr4;
  603. settings.V0Behavior = NSQLTranslation::EV0Behavior::Report;
  604. settings.AssumeYdbOnClusterWithSlash = RunOptions_.AssumeYdbOnClusterWithSlash;
  605. if (ERunMode::Discover == RunOptions_.Mode) {
  606. settings.Mode = NSQLTranslation::ESqlMode::DISCOVERY;
  607. }
  608. if (!program->ParseSql(settings)) {
  609. program->PrintErrorsTo(*RunOptions_.ErrStream);
  610. fail = true;
  611. }
  612. if (!fail && RunOptions_.TestSqlFormat && 1 == RunOptions_.SyntaxVersion) {
  613. TString formattedProgramText;
  614. NYql::TIssues issues;
  615. auto formatter = NSQLFormat::MakeSqlFormatter(settings);
  616. if (!formatter->Format(RunOptions_.ProgramText, formattedProgramText, issues)) {
  617. *RunOptions_.ErrStream << "Format failed" << Endl;
  618. issues.PrintTo(*RunOptions_.ErrStream);
  619. return -1;
  620. }
  621. auto frmProgram = factory.Create("formatted SQL", formattedProgramText);
  622. if (!frmProgram->ParseSql(settings)) {
  623. frmProgram->PrintErrorsTo(*RunOptions_.ErrStream);
  624. return -1;
  625. }
  626. TStringStream srcQuery, frmQuery;
  627. program->AstRoot()->PrettyPrintTo(srcQuery, PRETTY_FLAGS);
  628. frmProgram->AstRoot()->PrettyPrintTo(frmQuery, PRETTY_FLAGS);
  629. if (srcQuery.Str() != frmQuery.Str()) {
  630. *RunOptions_.ErrStream << "source query's AST and formatted query's AST are not same" << Endl;
  631. return -1;
  632. }
  633. }
  634. } else {
  635. RunOptions_.PrintInfo("Parse YQL...");
  636. if (!program->ParseYql()) {
  637. program->PrintErrorsTo(*RunOptions_.ErrStream);
  638. fail = true;
  639. }
  640. }
  641. if (RunOptions_.TraceOptStream) {
  642. if (auto ast = program->GetQueryAst()) {
  643. *RunOptions_.TraceOptStream << *ast << Endl;
  644. }
  645. }
  646. if (fail) {
  647. return -1;
  648. }
  649. if (RunOptions_.PrintAst) {
  650. program->AstRoot()->PrettyPrintTo(Cout, PRETTY_FLAGS);
  651. }
  652. if (ERunMode::Parse == RunOptions_.Mode) {
  653. return 0;
  654. }
  655. RunOptions_.PrintInfo("Compile program...");
  656. if (!program->Compile(RunOptions_.User)) {
  657. program->PrintErrorsTo(*RunOptions_.ErrStream);
  658. fail = true;
  659. }
  660. if (RunOptions_.TraceOptStream) {
  661. program->Print(RunOptions_.TraceOptStream, nullptr);
  662. }
  663. if (fail) {
  664. return -1;
  665. }
  666. if (ERunMode::Compile == RunOptions_.Mode) {
  667. if (RunOptions_.ExprStream) {
  668. auto baseAst = ConvertToAst(*program->ExprRoot(), program->ExprCtx(), NYql::TExprAnnotationFlags::None, true);
  669. baseAst.Root->PrettyPrintTo(*RunOptions_.ExprStream, PRETTY_FLAGS);
  670. }
  671. return 0;
  672. }
  673. TProgram::TStatus status = DoRunProgram(program);
  674. if (ERunMode::Peephole == RunOptions_.Mode && RunOptions_.ExprStream && program->ExprRoot()) {
  675. auto ast = ConvertToAst(*program->ExprRoot(), program->ExprCtx(), RunOptions_.WithTypes ? TExprAnnotationFlags::Types : TExprAnnotationFlags::None, true);
  676. ui32 prettyFlags = TAstPrintFlags::ShortQuote;
  677. if (!RunOptions_.WithTypes) {
  678. prettyFlags |= TAstPrintFlags::PerLine;
  679. }
  680. ast.Root->PrettyPrintTo(*RunOptions_.ExprStream, prettyFlags);
  681. }
  682. if (RunOptions_.WithFinalIssues) {
  683. program->FinalizeIssues();
  684. }
  685. program->PrintErrorsTo(*RunOptions_.ErrStream);
  686. if (status == TProgram::TStatus::Error) {
  687. if (RunOptions_.TraceOptStream) {
  688. program->Print(RunOptions_.TraceOptStream, nullptr);
  689. }
  690. return -1;
  691. }
  692. if (!RunOptions_.FullExpr && ERunMode::Peephole != RunOptions_.Mode) {
  693. program->Print(RunOptions_.ExprStream, RunOptions_.PlanStream, /*cleanPlan*/true);
  694. }
  695. program->ConfigureYsonResultFormat(RunOptions_.ResultsFormat);
  696. if (RunOptions_.ResultStream) {
  697. RunOptions_.PrintInfo("Getting results...");
  698. if (ERunMode::Discover == RunOptions_.Mode) {
  699. if (auto data = program->GetDiscoveredData()) {
  700. *RunOptions_.ResultStream << *data;
  701. }
  702. } else if (ERunMode::Lineage == RunOptions_.Mode) {
  703. if (auto data = program->GetLineage()) {
  704. TStringInput in(*data);
  705. NYson::ReformatYsonStream(&in, RunOptions_.ResultStream, RunOptions_.ResultsFormat);
  706. }
  707. } else if (program->HasResults()) {
  708. if (RunOptions_.ValidateResultFormat) {
  709. auto str = program->ResultsAsString();
  710. if (!str.empty()) {
  711. auto node = NYT::NodeFromYsonString(str);
  712. for (const auto& r : NResult::ParseResponse(node)) {
  713. for (const auto& write : r.Writes) {
  714. if (write.Type) {
  715. NResult::TEmptyTypeVisitor visitor;
  716. NResult::ParseType(*write.Type, visitor);
  717. }
  718. if (write.Type && write.Data) {
  719. NResult::TEmptyDataVisitor visitor;
  720. NResult::ParseData(*write.Type, *write.Data, visitor);
  721. }
  722. }
  723. }
  724. }
  725. RunOptions_.ResultStream->Write(str.data(), str.size());
  726. } else {
  727. *RunOptions_.ResultStream << program->ResultsAsString();
  728. }
  729. }
  730. }
  731. if (RunOptions_.StatStream) {
  732. if (auto st = program->GetStatistics(!RunOptions_.FullStatistics)) {
  733. *RunOptions_.StatStream << *st;
  734. }
  735. }
  736. RunOptions_.PrintInfo("");
  737. RunOptions_.PrintInfo("Done");
  738. return 0;
  739. }
  740. TProgram::TStatus TFacadeRunner::DoRunProgram(TProgramPtr program) {
  741. TProgram::TStatus status = TProgram::TStatus::Ok;
  742. auto defOptConfig = TOptPipelineConfigurator(program, RunOptions_.FullExpr ? RunOptions_.PlanStream : nullptr, RunOptions_.FullExpr ? RunOptions_.ExprStream : nullptr, RunOptions_.WithTypes);
  743. IPipelineConfigurator* optConfig = OptPipelineConfigurator_ ? OptPipelineConfigurator_ : &defOptConfig;
  744. if (ERunMode::Peephole == RunOptions_.Mode) {
  745. RunOptions_.PrintInfo("Peephole...");
  746. auto defConfig = TPeepHolePipelineConfigurator();
  747. IPipelineConfigurator* config = PeepholePipelineConfigurator_ ? PeepholePipelineConfigurator_ : &defConfig;
  748. status = program->OptimizeWithConfig(RunOptions_.User, *config);
  749. } else if (ERunMode::Run == RunOptions_.Mode) {
  750. RunOptions_.PrintInfo("Run program...");
  751. status = program->RunWithConfig(RunOptions_.User, *optConfig);
  752. } else if (ERunMode::Optimize == RunOptions_.Mode) {
  753. RunOptions_.PrintInfo("Optimize program...");
  754. status = program->OptimizeWithConfig(RunOptions_.User, *optConfig);
  755. } else if (ERunMode::Validate == RunOptions_.Mode) {
  756. RunOptions_.PrintInfo("Validate program...");
  757. status = program->Validate(RunOptions_.User, RunOptions_.ExprStream, RunOptions_.WithTypes);
  758. } else if (ERunMode::Discover == RunOptions_.Mode) {
  759. RunOptions_.PrintInfo("Discover program...");
  760. status = program->Discover(RunOptions_.User);
  761. } else if (ERunMode::Lineage == RunOptions_.Mode) {
  762. RunOptions_.PrintInfo("Calculating lineage in program...");
  763. status = program->LineageWithConfig(RunOptions_.User, *optConfig);
  764. }
  765. return status;
  766. }
  767. } // NYql