summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvvvv <[email protected]>2025-09-22 13:47:31 +0300
committervvvv <[email protected]>2025-09-22 14:09:17 +0300
commitfcacd313e6f9c84b89fe898b489cd8de620b4cf1 (patch)
treead75dbdef75ff5659bac782e6160fbf1685a66e0
parent44df5156d21c3bf19af3045035748352a0d3713f (diff)
YQL-20339 expr high level funcs
init commit_hash:479f16e9cd255b616573d811910403290f9ef656
-rw-r--r--yql/essentials/core/common_opt/yql_co_simple1.cpp29
-rw-r--r--yql/essentials/core/type_ann/type_ann_core.cpp9
-rw-r--r--yql/essentials/core/type_ann/type_ann_dict.cpp68
-rw-r--r--yql/essentials/core/type_ann/type_ann_dict.h3
-rw-r--r--yql/essentials/core/type_ann/type_ann_impl.h1
-rw-r--r--yql/essentials/core/type_ann/type_ann_list.cpp5
-rw-r--r--yql/essentials/data/language/sql_functions.json16
-rw-r--r--yql/essentials/sql/v1/builtin.cpp5
-rw-r--r--yql/essentials/tests/sql/minirun/part1/canondata/result.json42
-rw-r--r--yql/essentials/tests/sql/minirun/part6/canondata/result.json14
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/result.json48
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_insert_/formatted.sql5
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_remove_/formatted.sql5
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_update_/formatted.sql5
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_upsert_/formatted.sql5
-rw-r--r--yql/essentials/tests/sql/suites/linear/dict_insert.yql1
-rw-r--r--yql/essentials/tests/sql/suites/linear/dict_remove.yql1
-rw-r--r--yql/essentials/tests/sql/suites/linear/dict_update.yql1
-rw-r--r--yql/essentials/tests/sql/suites/linear/dict_upsert.yql1
19 files changed, 259 insertions, 5 deletions
diff --git a/yql/essentials/core/common_opt/yql_co_simple1.cpp b/yql/essentials/core/common_opt/yql_co_simple1.cpp
index 339cc3b8947..9a0d5398d48 100644
--- a/yql/essentials/core/common_opt/yql_co_simple1.cpp
+++ b/yql/essentials/core/common_opt/yql_co_simple1.cpp
@@ -6370,6 +6370,35 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
+ map["DictInsert"] = map["DictUpsert"] = map["DictUpdate"] = map["DictRemove"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
+ Y_UNUSED(optCtx);
+ YQL_CLOG(DEBUG, Core) << node->Content();
+ return ctx.Builder(node->Pos())
+ .Callable("Block")
+ .Lambda(0)
+ .Param("parent")
+ .Callable("FromMutDict")
+ .Callable(0, TString("Mut") + node->Content())
+ .Callable(0, "ToMutDict")
+ .Add(0, node->HeadPtr())
+ .Callable(1, "DependsOn")
+ .Arg(0, "parent")
+ .Seal()
+ .Seal()
+ .Do([&](TExprNodeBuilder& builder) -> TExprNodeBuilder& {
+ for (ui32 i = 1; i < node->ChildrenSize(); ++i) {
+ builder.Add(i, node->ChildPtr(i));
+ }
+
+ return builder;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ };
+
map["HasNull"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
YQL_CLOG(DEBUG, Core) << node->Content();
diff --git a/yql/essentials/core/type_ann/type_ann_core.cpp b/yql/essentials/core/type_ann/type_ann_core.cpp
index 84db869b4e7..dad72c365e8 100644
--- a/yql/essentials/core/type_ann/type_ann_core.cpp
+++ b/yql/essentials/core/type_ann/type_ann_core.cpp
@@ -52,6 +52,11 @@ namespace NYql {
}
namespace NTypeAnnImpl {
+ TExprNodeBuilder& AddChildren(TExprNodeBuilder& builder, ui32 index, const TExprNode::TPtr& input) {
+ const auto i = index;
+ return i >= input->ChildrenSize() ? builder : AddChildren(builder.Add(i, input->ChildPtr(i)), ++index, input);
+ }
+
const TTypeAnnotationNode* ParseTypeCached(const TString& typeStr, TExprContext& ctx, TTypeAnnotationContext& typeCtx) {
if (!ctx.ParseTypeCache.contains(typeStr)) {
auto typeNode = ctx.Builder({})
@@ -13093,6 +13098,10 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
ExtFunctions["MutDictItems"] = &MutDictItemsWrapper;
ExtFunctions["MutDictKeys"] = &MutDictKeysWrapper;
ExtFunctions["MutDictPayloads"] = &MutDictPayloadsWrapper;
+ ExtFunctions["DictInsert"] = &DictBlindOpWrapper<true>;
+ ExtFunctions["DictUpsert"] = &DictBlindOpWrapper<true>;
+ ExtFunctions["DictUpdate"] = &DictBlindOpWrapper<true>;
+ ExtFunctions["DictRemove"] = &DictBlindOpWrapper<false>;
Functions["Nothing"] = &NothingWrapper;
Functions["AsOptionalType"] = &AsOptionalTypeWrapper;
Functions["List"] = &ListWrapper;
diff --git a/yql/essentials/core/type_ann/type_ann_dict.cpp b/yql/essentials/core/type_ann/type_ann_dict.cpp
index 476f7a31f4d..5afdffcdb4c 100644
--- a/yql/essentials/core/type_ann/type_ann_dict.cpp
+++ b/yql/essentials/core/type_ann/type_ann_dict.cpp
@@ -384,8 +384,76 @@ IGraphTransformer::TStatus MutDictPayloadsWrapper(const TExprNode::TPtr& input,
return IGraphTransformer::TStatus::Ok;
}
+template <bool WithPayload>
+IGraphTransformer::TStatus DictBlindOpWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ Y_UNUSED(output);
+ if (!CheckLinearLangver(input->Pos(), ctx.Types.LangVer, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!EnsureArgsCount(*input, 2 + (WithPayload ? 1 : 0), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (IsNull(input->Head())) {
+ output = input->HeadPtr();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ if (!EnsureComputable(input->Head(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ bool isOptional = false;
+ auto type = input->Head().GetTypeAnn();
+ if (type->GetKind() == ETypeAnnotationKind::Optional) {
+ type = type->Cast<TOptionalExprType>()->GetItemType();
+ isOptional = true;
+ }
+
+ if (type->GetKind() != ETypeAnnotationKind::Dict) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), TStringBuilder()
+ << "Expected dict or optional of dict, but got: " << *input->Head().GetTypeAnn()));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (isOptional) {
+ output = AddChildren(ctx.Expr.Builder(input->Pos())
+ .Callable("Map")
+ .Add(0, input->HeadPtr())
+ .Lambda(1)
+ .Param("x")
+ .Callable(input->Content())
+ .Arg(0, "x"), 1U, input)
+ .Seal()
+ .Seal()
+ .Seal().Build();
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
+ auto dictType = type->Cast<TDictExprType>();
+ auto status = TryConvertTo(input->ChildRef(1), *dictType->GetKeyType(), ctx.Expr, ctx.Types);
+ if (status != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+
+ if constexpr (WithPayload) {
+ status = TryConvertTo(input->ChildRef(2), *dictType->GetPayloadType(), ctx.Expr, ctx.Types);
+ if (status != IGraphTransformer::TStatus::Ok) {
+ return status;
+ }
+ }
+
+ input->SetTypeAnn(input->Head().GetTypeAnn());
+ return IGraphTransformer::TStatus::Ok;
+}
+
template IGraphTransformer::TStatus MutDictBlindOpWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
template IGraphTransformer::TStatus MutDictBlindOpWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+template IGraphTransformer::TStatus DictBlindOpWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+template IGraphTransformer::TStatus DictBlindOpWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+
+
} // namespace NTypeAnnImpl
} // namespace NYql
diff --git a/yql/essentials/core/type_ann/type_ann_dict.h b/yql/essentials/core/type_ann/type_ann_dict.h
index 7f4ea5cd4e6..5ce9c073430 100644
--- a/yql/essentials/core/type_ann/type_ann_dict.h
+++ b/yql/essentials/core/type_ann/type_ann_dict.h
@@ -24,5 +24,8 @@ IGraphTransformer::TStatus MutDictItemsWrapper(const TExprNode::TPtr& input, TEx
IGraphTransformer::TStatus MutDictKeysWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
IGraphTransformer::TStatus MutDictPayloadsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+template <bool WithPayload>
+IGraphTransformer::TStatus DictBlindOpWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+
} // namespace NTypeAnnImpl
} // namespace NYql
diff --git a/yql/essentials/core/type_ann/type_ann_impl.h b/yql/essentials/core/type_ann/type_ann_impl.h
index b7bd3776da9..32d275e71bc 100644
--- a/yql/essentials/core/type_ann/type_ann_impl.h
+++ b/yql/essentials/core/type_ann/type_ann_impl.h
@@ -25,6 +25,7 @@ namespace NTypeAnnImpl {
};
const TTypeAnnotationNode* ParseTypeCached(const TString& typeStr, TExprContext& ctx, TTypeAnnotationContext& typeCtx);
+ TExprNodeBuilder& AddChildren(TExprNodeBuilder& builder, ui32 index, const TExprNode::TPtr& input);
// Implemented in type_ann_join.cpp
IGraphTransformer::TStatus JoinWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
diff --git a/yql/essentials/core/type_ann/type_ann_list.cpp b/yql/essentials/core/type_ann/type_ann_list.cpp
index 3ecf87c417c..059c5e58d3c 100644
--- a/yql/essentials/core/type_ann/type_ann_list.cpp
+++ b/yql/essentials/core/type_ann/type_ann_list.cpp
@@ -1364,11 +1364,6 @@ namespace {
template IGraphTransformer::TStatus MultiMapWrapper<true>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
template IGraphTransformer::TStatus MultiMapWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- TExprNodeBuilder& AddChildren(TExprNodeBuilder& builder, ui32 index, const TExprNode::TPtr& input) {
- const auto i = index;
- return i >= input->ChildrenSize() ? builder : AddChildren(builder.Add(i, input->ChildPtr(i)), ++index, input);
- }
-
template<ui32 MinArgsCount = 2U, ui32 MaxArgsCount = MinArgsCount, bool UseFlatMap = false>
IGraphTransformer::TStatus OptListWrapperImpl(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx,
TStringBuf name) {
diff --git a/yql/essentials/data/language/sql_functions.json b/yql/essentials/data/language/sql_functions.json
index 75bbc3a6ad6..074cb24e656 100644
--- a/yql/essentials/data/language/sql_functions.json
+++ b/yql/essentials/data/language/sql_functions.json
@@ -348,6 +348,10 @@
"kind": "Normal"
},
{
+ "name": "DictInsert",
+ "kind": "Normal"
+ },
+ {
"name": "DictItems",
"kind": "Normal"
},
@@ -376,6 +380,10 @@
"kind": "Normal"
},
{
+ "name": "DictRemove",
+ "kind": "Normal"
+ },
+ {
"name": "DictType",
"kind": "Normal"
},
@@ -388,6 +396,14 @@
"kind": "Normal"
},
{
+ "name": "DictUpdate",
+ "kind": "Normal"
+ },
+ {
+ "name": "DictUpsert",
+ "kind": "Normal"
+ },
+ {
"name": "DynamicLinearTypeHandle",
"kind": "Normal"
},
diff --git a/yql/essentials/sql/v1/builtin.cpp b/yql/essentials/sql/v1/builtin.cpp
index 13eb074abc9..077b3d9fed5 100644
--- a/yql/essentials/sql/v1/builtin.cpp
+++ b/yql/essentials/sql/v1/builtin.cpp
@@ -3099,6 +3099,11 @@ struct TBuiltinFuncData {
{"mutdictkeys", {"MutDictKeys", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("MutDictKeys", 1, 1)}},
{"mutdictpayloads", {"MutDictPayloads", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("MutDictPayloads", 1, 1)}},
+ {"dictinsert", {"DictInsert", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictInsert", 3, 3)}},
+ {"dictupsert", {"DictUpsert", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictUpsert", 3, 3)}},
+ {"dictupdate", {"DictUpdate", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictUpdate", 3, 3)}},
+ {"dictremove", {"DictRemove", "Normal", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictRemove", 2, 2)}},
+
// Atom builtins
{"asatom", {"AsAtom", "Normal", BuildSimpleBuiltinFactoryCallback<TYqlAsAtom>()}},
{"secureparam", {"SecureParam", "Normal", BuildNamedBuiltinFactoryCallback<TYqlAtom>("SecureParam")}},
diff --git a/yql/essentials/tests/sql/minirun/part1/canondata/result.json b/yql/essentials/tests/sql/minirun/part1/canondata/result.json
index a31915161db..3371a2fc569 100644
--- a/yql/essentials/tests/sql/minirun/part1/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part1/canondata/result.json
@@ -895,6 +895,48 @@
"uri": "https://{canondata_backend}/1937001/77bd704576aa33edf60032c4b55577e01f4f1058/resource.tar.gz#test.test_linear-block-default.txt-Results_/results.txt"
}
],
+ "test.test[linear-dict_insert-default.txt-Debug]": [
+ {
+ "checksum": "4adfc42dddaa0fd891d167626875ff54",
+ "size": 451,
+ "uri": "https://{canondata_backend}/1942278/0e95723ca3d70727d9453dfcda265b8262b4c0ea/resource.tar.gz#test.test_linear-dict_insert-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[linear-dict_insert-default.txt-Results]": [
+ {
+ "checksum": "5f596f017ba6e0df823238c064e9c913",
+ "size": 2700,
+ "uri": "https://{canondata_backend}/1942278/0e95723ca3d70727d9453dfcda265b8262b4c0ea/resource.tar.gz#test.test_linear-dict_insert-default.txt-Results_/results.txt"
+ }
+ ],
+ "test.test[linear-dict_remove-default.txt-Debug]": [
+ {
+ "checksum": "902ce46652ed409171a7067d96fd41e7",
+ "size": 533,
+ "uri": "https://{canondata_backend}/1942278/0e95723ca3d70727d9453dfcda265b8262b4c0ea/resource.tar.gz#test.test_linear-dict_remove-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[linear-dict_remove-default.txt-Results]": [
+ {
+ "checksum": "b8b9c1aba7099bfb0ebd560eedfc8bcf",
+ "size": 2294,
+ "uri": "https://{canondata_backend}/1942278/0e95723ca3d70727d9453dfcda265b8262b4c0ea/resource.tar.gz#test.test_linear-dict_remove-default.txt-Results_/results.txt"
+ }
+ ],
+ "test.test[linear-dict_upsert-default.txt-Debug]": [
+ {
+ "checksum": "642ad038057c1a4929303ff09c85ae5f",
+ "size": 561,
+ "uri": "https://{canondata_backend}/1942278/0e95723ca3d70727d9453dfcda265b8262b4c0ea/resource.tar.gz#test.test_linear-dict_upsert-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[linear-dict_upsert-default.txt-Results]": [
+ {
+ "checksum": "14c87d2a72ab905f156b001e927b2f19",
+ "size": 2548,
+ "uri": "https://{canondata_backend}/1942278/0e95723ca3d70727d9453dfcda265b8262b4c0ea/resource.tar.gz#test.test_linear-dict_upsert-default.txt-Results_/results.txt"
+ }
+ ],
"test.test[linear-mutdict_copy-default.txt-Debug]": [
{
"checksum": "b119ff749cf72f03eaea4d1f5edd914e",
diff --git a/yql/essentials/tests/sql/minirun/part6/canondata/result.json b/yql/essentials/tests/sql/minirun/part6/canondata/result.json
index 71d782ea2e1..3d476f452ab 100644
--- a/yql/essentials/tests/sql/minirun/part6/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part6/canondata/result.json
@@ -1029,6 +1029,20 @@
"uri": "https://{canondata_backend}/1871102/cf0bf303bf8ddaa5f80dc41d0b1079fd931793f8/resource.tar.gz#test.test_like-ilike-Ansi-Results_/results.txt"
}
],
+ "test.test[linear-dict_update-default.txt-Debug]": [
+ {
+ "checksum": "d4bf7b5307cbf2ec9b0943e230c0fe9a",
+ "size": 561,
+ "uri": "https://{canondata_backend}/1942415/df3e80ac994c18318b1f7c88f726afeb48326be8/resource.tar.gz#test.test_linear-dict_update-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[linear-dict_update-default.txt-Results]": [
+ {
+ "checksum": "489dc346769a9ecaf47aa338990093b6",
+ "size": 2412,
+ "uri": "https://{canondata_backend}/1942415/df3e80ac994c18318b1f7c88f726afeb48326be8/resource.tar.gz#test.test_linear-dict_update-default.txt-Results_/results.txt"
+ }
+ ],
"test.test[linear-mutdict_contains-default.txt-Debug]": [
{
"checksum": "46e4961f3a6861e7cf1dc80e89733cdb",
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/result.json b/yql/essentials/tests/sql/sql2yql/canondata/result.json
index 3978b671e1d..c602b838881 100644
--- a/yql/essentials/tests/sql/sql2yql/canondata/result.json
+++ b/yql/essentials/tests/sql/sql2yql/canondata/result.json
@@ -4983,6 +4983,34 @@
"uri": "https://{canondata_backend}/1916746/a4033d596240165caf2006fc0780a730bc526f0d/resource.tar.gz#test_sql2yql.test_linear-block_/sql.yql"
}
],
+ "test_sql2yql.test[linear-dict_insert]": [
+ {
+ "checksum": "dc725f2114edde83cfb60cf48740edfc",
+ "size": 1489,
+ "uri": "https://{canondata_backend}/1942278/f5fdbe9e3fc56fe8d0f7d73b0c46910a2483dcbd/resource.tar.gz#test_sql2yql.test_linear-dict_insert_/sql.yql"
+ }
+ ],
+ "test_sql2yql.test[linear-dict_remove]": [
+ {
+ "checksum": "cb1a67570ed65c20bb711055110d6025",
+ "size": 1450,
+ "uri": "https://{canondata_backend}/1942278/f5fdbe9e3fc56fe8d0f7d73b0c46910a2483dcbd/resource.tar.gz#test_sql2yql.test_linear-dict_remove_/sql.yql"
+ }
+ ],
+ "test_sql2yql.test[linear-dict_update]": [
+ {
+ "checksum": "e632c8feda80959be7ee08ffd8a65958",
+ "size": 1489,
+ "uri": "https://{canondata_backend}/1942278/f5fdbe9e3fc56fe8d0f7d73b0c46910a2483dcbd/resource.tar.gz#test_sql2yql.test_linear-dict_update_/sql.yql"
+ }
+ ],
+ "test_sql2yql.test[linear-dict_upsert]": [
+ {
+ "checksum": "c54d36ea40f1b790bb4c553d9d1913a5",
+ "size": 1489,
+ "uri": "https://{canondata_backend}/1942278/f5fdbe9e3fc56fe8d0f7d73b0c46910a2483dcbd/resource.tar.gz#test_sql2yql.test_linear-dict_upsert_/sql.yql"
+ }
+ ],
"test_sql2yql.test[linear-mutdict_contains]": [
{
"checksum": "dcd70eb662e088e8f1e8b937f86447b4",
@@ -12120,6 +12148,26 @@
"uri": "file://test_sql_format.test_linear-block_/formatted.sql"
}
],
+ "test_sql_format.test[linear-dict_insert]": [
+ {
+ "uri": "file://test_sql_format.test_linear-dict_insert_/formatted.sql"
+ }
+ ],
+ "test_sql_format.test[linear-dict_remove]": [
+ {
+ "uri": "file://test_sql_format.test_linear-dict_remove_/formatted.sql"
+ }
+ ],
+ "test_sql_format.test[linear-dict_update]": [
+ {
+ "uri": "file://test_sql_format.test_linear-dict_update_/formatted.sql"
+ }
+ ],
+ "test_sql_format.test[linear-dict_upsert]": [
+ {
+ "uri": "file://test_sql_format.test_linear-dict_upsert_/formatted.sql"
+ }
+ ],
"test_sql_format.test[linear-mutdict_contains]": [
{
"uri": "file://test_sql_format.test_linear-mutdict_contains_/formatted.sql"
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_insert_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_insert_/formatted.sql
new file mode 100644
index 00000000000..e8748aaa714
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_insert_/formatted.sql
@@ -0,0 +1,5 @@
+SELECT
+ DictInsert(NULL, 'foo', 1),
+ DictInsert(Just({'bar': 2}), 'foo', 1),
+ DictInsert({'bar': 2}, 'foo', 1)
+;
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_remove_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_remove_/formatted.sql
new file mode 100644
index 00000000000..0c3cff9fcd1
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_remove_/formatted.sql
@@ -0,0 +1,5 @@
+SELECT
+ DictRemove(NULL, 'foo'),
+ DictRemove(Just({'bar': 2}), 'bar'),
+ DictRemove({'bar': 2}, 'foo')
+;
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_update_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_update_/formatted.sql
new file mode 100644
index 00000000000..a3434145c3c
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_update_/formatted.sql
@@ -0,0 +1,5 @@
+SELECT
+ DictUpdate(NULL, 'foo', 1),
+ DictUpdate(Just({'bar': 2}), 'bar', 1),
+ DictUpdate({'bar': 2}, 'foo', 1)
+;
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_upsert_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_upsert_/formatted.sql
new file mode 100644
index 00000000000..45fa42dbbd4
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_linear-dict_upsert_/formatted.sql
@@ -0,0 +1,5 @@
+SELECT
+ DictUpsert(NULL, 'foo', 1),
+ DictUpsert(Just({'bar': 2}), 'bar', 1),
+ DictUpsert({'bar': 2}, 'foo', 1)
+;
diff --git a/yql/essentials/tests/sql/suites/linear/dict_insert.yql b/yql/essentials/tests/sql/suites/linear/dict_insert.yql
new file mode 100644
index 00000000000..c6ccaa9805b
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/linear/dict_insert.yql
@@ -0,0 +1 @@
+select DictInsert(NULL,'foo',1),DictInsert(Just({'bar':2}),'foo',1),DictInsert({'bar':2},'foo',1) \ No newline at end of file
diff --git a/yql/essentials/tests/sql/suites/linear/dict_remove.yql b/yql/essentials/tests/sql/suites/linear/dict_remove.yql
new file mode 100644
index 00000000000..564d97cf89b
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/linear/dict_remove.yql
@@ -0,0 +1 @@
+select DictRemove(NULL,'foo'),DictRemove(Just({'bar':2}),'bar'),DictRemove({'bar':2},'foo') \ No newline at end of file
diff --git a/yql/essentials/tests/sql/suites/linear/dict_update.yql b/yql/essentials/tests/sql/suites/linear/dict_update.yql
new file mode 100644
index 00000000000..14c279850b2
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/linear/dict_update.yql
@@ -0,0 +1 @@
+select DictUpdate(NULL,'foo',1),DictUpdate(Just({'bar':2}),'bar',1),DictUpdate({'bar':2},'foo',1) \ No newline at end of file
diff --git a/yql/essentials/tests/sql/suites/linear/dict_upsert.yql b/yql/essentials/tests/sql/suites/linear/dict_upsert.yql
new file mode 100644
index 00000000000..4a314b4e425
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/linear/dict_upsert.yql
@@ -0,0 +1 @@
+select DictUpsert(NULL,'foo',1),DictUpsert(Just({'bar':2}),'bar',1),DictUpsert({'bar':2},'foo',1) \ No newline at end of file