summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--yql/essentials/core/facade/yql_facade.cpp55
-rw-r--r--yql/essentials/core/facade/yql_facade.h2
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/result.json12
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_params-bad_dict_/formatted.sql6
-rw-r--r--yql/essentials/tests/sql/suites/params/bad_dict.cfg2
-rw-r--r--yql/essentials/tests/sql/suites/params/bad_dict.sql3
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;