summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Neporada <[email protected]>2022-06-14 18:22:39 +0300
committerAndrey Neporada <[email protected]>2022-06-14 18:22:39 +0300
commitdb0e3b59f3d00bff597665856acd9c956d1fe71f (patch)
treecebf78272de2779516045691a2b7c66835d8263f
parent83725a03a831a7665339c3bfc92750b8ec36d837 (diff)
[YQL-2610] Add setting to prohibit cast from Yson to string. Disable CAST from Yson to String in tests
ref:039e04a61aaeb02dc58968abe3755433b7158fcc
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_core.cpp21
-rw-r--r--ydb/library/yql/core/yql_type_annotation.h1
-rw-r--r--ydb/library/yql/providers/config/yql_config_provider.cpp8
-rw-r--r--ydb/library/yql/sql/v1/context.h1
-rw-r--r--ydb/library/yql/sql/v1/query.cpp5
-rw-r--r--ydb/library/yql/sql/v1/sql.cpp16
6 files changed, 45 insertions, 7 deletions
diff --git a/ydb/library/yql/core/type_ann/type_ann_core.cpp b/ydb/library/yql/core/type_ann/type_ann_core.cpp
index 3f84541a4e3..a2e20dcc89c 100644
--- a/ydb/library/yql/core/type_ann/type_ann_core.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_core.cpp
@@ -3905,7 +3905,7 @@ namespace NTypeAnnImpl {
}
template <bool Strong>
- IGraphTransformer::TStatus CastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus CastWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4000,10 +4000,17 @@ namespace NTypeAnnImpl {
}
if (sourceDataType->GetSlot() == EDataSlot::Yson && targetDataType->GetSlot() == EDataSlot::String) {
- auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Consider using ToBytes to get internal representation of Yson type,"
- " or Yson::ConvertToString* methods to get string values");
- SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_CORE_CAST_YSON_JSON_BYTES, issue);
- if (!ctx.Expr.AddWarning(issue)) {
+ const TString msg = "Consider using ToBytes to get internal representation of Yson type,"
+ " or Yson::ConvertToString* methods to get string values";
+ if (ctx.Types.YsonCastToString) {
+ auto issue = TIssue(ctx.Expr.GetPosition(input->Head().Pos()), msg);
+ SetIssueCode(EYqlIssueCode::TIssuesIds_EIssueCode_CORE_CAST_YSON_JSON_BYTES, issue);
+ if (!ctx.Expr.AddWarning(issue)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+ } else {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()),
+ TStringBuilder() << "Casting Yson to String is ambiguous. " << msg));
return IGraphTransformer::TStatus::Error;
}
}
@@ -11078,8 +11085,6 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["AlterTo"] = &AlterToWrapper;
Functions["ToIntegral"] = &ToIntegralWrapper;
Functions["Cast"] = &OldCastWrapper;
- Functions["SafeCast"] = &CastWrapper<false>;
- Functions["StrictCast"] = &CastWrapper<true>;
Functions["BitCast"] = &BitCastWrapper;
Functions["WidenIntegral"] = &WidenIntegralWrapper;
Functions["Default"] = &DefaultWrapper;
@@ -11471,6 +11476,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
ExtFunctions["AssumeColumnOrder"] = &AssumeColumnOrderWrapper;
ExtFunctions["AssumeColumnOrderPartial"] = &AssumeColumnOrderWrapper;
ExtFunctions["UnionAllPositional"] = &UnionAllPositionalWrapper;
+ ExtFunctions["SafeCast"] = &CastWrapper<false>;
+ ExtFunctions["StrictCast"] = &CastWrapper<true>;
ColumnOrderFunctions["PgSetItem"] = &OrderForPgSetItem;
ColumnOrderFunctions["AssumeColumnOrder"] = &OrderForAssumeColumnOrder;
diff --git a/ydb/library/yql/core/yql_type_annotation.h b/ydb/library/yql/core/yql_type_annotation.h
index 32d267be440..6333bd75992 100644
--- a/ydb/library/yql/core/yql_type_annotation.h
+++ b/ydb/library/yql/core/yql_type_annotation.h
@@ -220,6 +220,7 @@ struct TTypeAnnotationContext: public TThrRefBase {
TString DqFallbackPolicy = "";
bool StrictTableProps = true;
bool JsonQueryReturnsJsonDocument = false;
+ bool YsonCastToString = true;
ui32 FolderSubDirsLimit = 1000;
// compatibility with v0 or raw s-expression code
diff --git a/ydb/library/yql/providers/config/yql_config_provider.cpp b/ydb/library/yql/providers/config/yql_config_provider.cpp
index 6952e96cf07..ec5309a8503 100644
--- a/ydb/library/yql/providers/config/yql_config_provider.cpp
+++ b/ydb/library/yql/providers/config/yql_config_provider.cpp
@@ -745,6 +745,14 @@ namespace {
return false;
}
}
+ else if (name == "YsonCastToString" || name == "DisableYsonCastToString") {
+ if (args.size() != 0) {
+ ctx.AddError(TIssue(pos, TStringBuilder() << "Expected no arguments, but got " << args.size()));
+ return false;
+ }
+
+ Types.YsonCastToString = (name == "YsonCastToString");
+ }
else {
ctx.AddError(TIssue(pos, TStringBuilder() << "Unsupported command: " << name));
return false;
diff --git a/ydb/library/yql/sql/v1/context.h b/ydb/library/yql/sql/v1/context.h
index bc446962b08..f4bd15847ee 100644
--- a/ydb/library/yql/sql/v1/context.h
+++ b/ydb/library/yql/sql/v1/context.h
@@ -264,6 +264,7 @@ namespace NSQLTranslationV1 {
bool FlexibleTypes = false;
// see YQL-10265
bool AnsiCurrentRow = false;
+ TMaybe<bool> YsonCastToString;
THashMap<TString, TMaybe<TString>> Libraries; // alias -> optional file
THashMap<TString, ui32> PackageVersions;
NYql::TWarningPolicy WarningPolicy;
diff --git a/ydb/library/yql/sql/v1/query.cpp b/ydb/library/yql/sql/v1/query.cpp
index df41d79a877..d054a383958 100644
--- a/ydb/library/yql/sql/v1/query.cpp
+++ b/ydb/library/yql/sql/v1/query.cpp
@@ -1775,6 +1775,11 @@ public:
BuildQuotedAtom(Pos, "Attr"), BuildQuotedAtom(Pos, "Dummy_"), BuildQuotedAtom(Pos, "1"))));
}
}
+
+ if (ctx.YsonCastToString.Defined()) {
+ const TString pragmaName = *ctx.YsonCastToString ? "YsonCastToString" : "DisableYsonCastToString";
+ Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, pragmaName))));
+ }
}
}
diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp
index 0595f746906..8792f57f7c7 100644
--- a/ydb/library/yql/sql/v1/sql.cpp
+++ b/ydb/library/yql/sql/v1/sql.cpp
@@ -9777,6 +9777,22 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
}
return {};
+ } else if (normalizedPragma == "casttostring" || normalizedPragma == "disablecasttostring") {
+ const bool allow = normalizedPragma == "casttostring";
+ if (values.size() == 0U) {
+ Ctx.YsonCastToString = allow;
+ success = true;
+ return {};
+ }
+ bool pragmaYsonCastToString;
+ if (values.size() == 1U && values.front().GetLiteral() && TryFromString(*values.front().GetLiteral(), pragmaYsonCastToString)) {
+ Ctx.PragmaYsonStrict = allow ? pragmaYsonCastToString : !pragmaYsonCastToString;
+ success = true;
+ } else {
+ Error() << "Expected 'true', 'false' or no parameter for: " << pragma;
+ Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");
+ }
+ return {};
} else {
Error() << "Unknown pragma: '" << pragma << "'";
Ctx.IncrementMonCounter("sql_errors", "BadPragmaValue");