diff options
6 files changed, 74 insertions, 6 deletions
diff --git a/yql/essentials/core/facade/yql_facade.cpp b/yql/essentials/core/facade/yql_facade.cpp index 9acefb155d0..055378a3ff1 100644 --- a/yql/essentials/core/facade/yql_facade.cpp +++ b/yql/essentials/core/facade/yql_facade.cpp @@ -495,12 +495,34 @@ IPlanBuilder& TProgram::GetPlanBuilder() { void TProgram::SetParametersYson(const TString& parameters) { Y_ENSURE(!TypeCtx_, "TypeCtx_ already created"); - auto node = NYT::NodeFromYsonString(parameters); - YQL_ENSURE(node.IsMap()); - for (const auto& x : node.AsMap()) { - YQL_ENSURE(x.second.IsMap()); - YQL_ENSURE(x.second.HasKey("Data")); - YQL_ENSURE(x.second.Size() == 1); + NYT::TNode node; + try { + try { + node = NYT::NodeFromYsonString(parameters); + } catch (const std::exception& e) { + throw TErrorException(0) << "Invalid parameters: " << e.what(); + } + + if (!node.IsMap()) { + throw TErrorException(0) << "Invalid parameters: expected Map at first level"; + } + + for (const auto& x : node.AsMap()) { + if (!x.second.IsMap()) { + throw TErrorException(0) << "Invalid parameters: expected Map at second level"; + } + + if (!x.second.HasKey("Data")) { + throw TErrorException(0) << "Invalid parameters: expected Data key"; + } + + if (x.second.Size() != 1) { + throw TErrorException(0) << "Invalid parameters: expected Map with single element"; + } + } + } catch (const std::exception& e) { + ParametersIssue_ = ExceptionToIssue(e); + return; } OperationOptions_.ParametersYson = node; @@ -705,8 +727,25 @@ void TProgram::HandleTranslationSettings(NSQLTranslation::TTranslationSettings& } } +bool TProgram::CheckParameters() { + if (ParametersIssue_) { + if (!ExprCtx_) { + ExprCtx_.Reset(new TExprContext(NextUniqueId_)); + } + + ExprCtx_->AddError(*ParametersIssue_); + return false; + } + + return true; +} + bool TProgram::ParseYql() { YQL_PROFILE_FUNC(TRACE); + if (!CheckParameters()) { + return false; + } + YQL_ENSURE(SourceSyntax_ == ESourceSyntax::Unknown); SourceSyntax_ = ESourceSyntax::Yql; SyntaxVersion_ = 1; @@ -730,6 +769,10 @@ bool TProgram::ParseSql() { bool TProgram::ParseSql(const NSQLTranslation::TTranslationSettings& settings) { YQL_PROFILE_FUNC(TRACE); + if (!CheckParameters()) { + return false; + } + YQL_ENSURE(SourceSyntax_ == ESourceSyntax::Unknown); SourceSyntax_ = ESourceSyntax::Sql; SyntaxVersion_ = settings.SyntaxVersion; diff --git a/yql/essentials/core/facade/yql_facade.h b/yql/essentials/core/facade/yql_facade.h index 3269b14c0a9..20b623d31cf 100644 --- a/yql/essentials/core/facade/yql_facade.h +++ b/yql/essentials/core/facade/yql_facade.h @@ -358,6 +358,7 @@ private: TTypeAnnotationContextPtr GetAnnotationContext() const; TTypeAnnotationContextPtr ProvideAnnotationContext(const TString& username); bool CollectUsedClusters(); + bool CheckParameters(); NThreading::TFuture<void> OpenSession(const TString& username); @@ -448,6 +449,7 @@ private: TQContext QContext_; TMaybe<TString> GatewaysForMerge_; TIssues FinalIssues_; + TMaybe<TIssue> ParametersIssue_; }; void UpdateSqlFlagsFromQContext(const TQContext& qContext, THashSet<TString>& flags); diff --git a/yql/essentials/tests/sql/sql2yql/canondata/result.json b/yql/essentials/tests/sql/sql2yql/canondata/result.json index be9dfbf6929..d4a9e5b804f 100644 --- a/yql/essentials/tests/sql/sql2yql/canondata/result.json +++ b/yql/essentials/tests/sql/sql2yql/canondata/result.json @@ -4521,6 +4521,13 @@ "uri": "https://{canondata_backend}/1942173/99e88108149e222741552e7e6cddef041d6a2846/resource.tar.gz#test_sql2yql.test_order_by-tuple01_/sql.yql" } ], + "test_sql2yql.test[params-bad_dict]": [ + { + "checksum": "de90a977f1e3e94ae2c6cb438cbf68cf", + "size": 1052, + "uri": "https://{canondata_backend}/1946324/70c05a25360e59ed701e167d489f84e1b53fece9/resource.tar.gz#test_sql2yql.test_params-bad_dict_/sql.yql" + } + ], "test_sql2yql.test[params-dict]": [ { "checksum": "f9d9d2f637f3375d580a94c58f8a1aeb", @@ -10600,6 +10607,11 @@ "uri": "file://test_sql_format.test_order_by-tuple01_/formatted.sql" } ], + "test_sql_format.test[params-bad_dict]": [ + { + "uri": "file://test_sql_format.test_params-bad_dict_/formatted.sql" + } + ], "test_sql_format.test[params-dict]": [ { "uri": "file://test_sql_format.test_params-dict_/formatted.sql" diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_params-bad_dict_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_params-bad_dict_/formatted.sql new file mode 100644 index 00000000000..312964d8d98 --- /dev/null +++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_params-bad_dict_/formatted.sql @@ -0,0 +1,6 @@ +/* custom error:Failed to parse data for parameter: $x*/ +DECLARE $x AS Dict<string, string>; + +SELECT + $x +; diff --git a/yql/essentials/tests/sql/suites/params/bad_dict.cfg b/yql/essentials/tests/sql/suites/params/bad_dict.cfg new file mode 100644 index 00000000000..f3400355907 --- /dev/null +++ b/yql/essentials/tests/sql/suites/params/bad_dict.cfg @@ -0,0 +1,2 @@ +xfail +param $x p_bool.json diff --git a/yql/essentials/tests/sql/suites/params/bad_dict.sql b/yql/essentials/tests/sql/suites/params/bad_dict.sql new file mode 100644 index 00000000000..547e45627a3 --- /dev/null +++ b/yql/essentials/tests/sql/suites/params/bad_dict.sql @@ -0,0 +1,3 @@ +/* custom error:Failed to parse data for parameter: $x*/ +declare $x as Dict<string,string>; +select $x; |
