diff options
author | vvvv <vvvv@ydb.tech> | 2023-11-29 14:45:00 +0300 |
---|---|---|
committer | vvvv <vvvv@ydb.tech> | 2023-11-29 16:52:53 +0300 |
commit | f1fff7b08e554137ba4015c332d072cfdc954621 (patch) | |
tree | c602fe8dd5175490bb59f07ca869d95bb19f8388 | |
parent | 07d2ecc7f0770d65dc3d853051d526ae27f72976 (diff) | |
download | ydb-f1fff7b08e554137ba4015c332d072cfdc954621.tar.gz |
YQL-17246 List <-> Tuple
7 files changed, 143 insertions, 0 deletions
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/list.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/list.md index dfa7da4afd..1674d290dd 100644 --- a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/list.md +++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/list.md @@ -857,3 +857,38 @@ SELECT ToSet($l); -- {1,2,3} ToSet(List<T>)->Set<T> ToSet(List<T>?)->Set<T>? ``` + +## ListFromTuple +Строит список из кортежа, в котором типы элементов совместимы друг с другом. Для опционального кортежа на выходе получается опциональный список. Для NULL аргумента - NULL. Для пустого кортежа - EmptyList. + +**Примеры** +```yql +$t = (1,2,3); +SELECT ListFromTuple($t); -- [1,2,3] +``` + +**Сигнатура** +``` +ListFromTuple(Null)->Null +ListFromTuple(Tuple<>)->EmptyList +ListFromTuple(Tuple<T1,T2,...>)->List<T> +ListFromTuple(Tuple<T1,T2,...>?)->List<T>? +``` + +## ListToTuple +Строит кортеж из списка и явно указанной ширины кортежа. Все элементы кортежа будут иметь тот же тип, что и тип элемента списка. Если длина списка не соотвествует указанной ширине кортежа, будет возвращена ошибка. Для опционального списка на выходе получается опциональный кортеж. Для NULL аргумента - NULL. + +**Примеры** +```yql +$l = [1,2,3]; +SELECT ListToTuple($l, 3); -- (1,2,3) +``` + +**Сигнатура** +``` +ListToTuple(Null,N)->Null +ListToTuple(EmptyList,N)->()) -- N должен быть 0 +ListToTuple(List<T>, N)->Tuple<T,T,...T> -- ширина кортежа N +ListToTuple(List<T>?, N)->Tuple<T,T,...T>? -- ширина кортежа N +``` + diff --git a/ydb/library/yql/mount/lib/yql/core.yql b/ydb/library/yql/mount/lib/yql/core.yql index f297cafde3..ea51d9b5fc 100644 --- a/ydb/library/yql/mount/lib/yql/core.yql +++ b/ydb/library/yql/mount/lib/yql/core.yql @@ -442,6 +442,42 @@ def signature(script, name): (lambda '() (Apply SpreadMembersImpl list fields (Bool '1))))) ))) +(let ListFromTupleImpl (lambda '(tuple) (block '( + (let n (MatchType tuple 'Tuple (lambda '() (Length (TupleTypeComponents (TypeHandle (TypeOf tuple))))) (lambda '() (Uint32 '0)))) + (let lambdaCode (LambdaCode (lambda '(tupleCode) (block '( + (let items (Map (ListFromRange (Uint32 '0) n) (lambda '(i) + (FuncCode (String 'Nth) tupleCode (AtomCode (SafeCast i (DataType 'String))))))) + (return (FuncCode (String 'AsList) items)) + ))))) + (return (Apply (EvaluateCode lambdaCode) tuple)) +)))) + +(let ListToTupleImpl (lambda '(list n) (block '( + (let list (Ensure list (== (Length list) n) (String '"Mismatch length of list"))) + (let lambdaCode (LambdaCode (lambda '(listCode) (block '( + (let indexDictCode (FuncCode (String 'ToIndexDict) listCode)) + (let items (Map (ListFromRange (Uint32 '0) n) (lambda '(i) + (FuncCode (String 'Unwrap) (FuncCode (String 'Lookup) indexDictCode (ReprCode i)))))) + (return (ListCode items)) + ))))) + (return (Apply (EvaluateCode lambdaCode) list)))) +)) + +(let ListFromTuple (lambda '(tuple) + (MatchType tuple + 'Null (lambda '() (Null)) + 'Optional (lambda '() (Map tuple (lambda '(unpacked) (Apply ListFromTupleImpl unpacked)))) + (lambda '() (Apply ListFromTupleImpl tuple))) +)) + +(let ListToTuple (lambda '(list n) + (MatchType list + 'Null (lambda '() (Null)) + 'EmptyList (lambda '() (Ensure '() (== n (Uint32 '0)) (String '"Expected empty tuple") )) + 'Optional (lambda '() (Map list (lambda '(unpacked) (Apply ListToTupleImpl unpacked n)))) + (lambda '() (Apply ListToTupleImpl list n))) +)) + (export Equals) (export Unequals) (export FindIndex) @@ -477,4 +513,6 @@ def signature(script, name): (export ForceRenameMembers) (export SpreadMembers) (export ForceSpreadMembers) +(export ListFromTuple) +(export ListToTuple) ) diff --git a/ydb/library/yql/sql/v1/builtin.cpp b/ydb/library/yql/sql/v1/builtin.cpp index a9f6eb563d..70e5177c5b 100644 --- a/ydb/library/yql/sql/v1/builtin.cpp +++ b/ydb/library/yql/sql/v1/builtin.cpp @@ -3242,6 +3242,8 @@ struct TBuiltinFuncData { {"forcerenamemembers", { "ForceRenameMembers", 2, 2}}, {"spreadmembers", { "SpreadMembers", 2, 2}}, {"forcespreadmembers", { "ForceSpreadMembers", 2, 2}}, + {"listfromtuple", { "ListFromTuple", 1, 1}}, + {"listtotuple", { "ListToTuple", 2, 2}}, }; return coreFuncs; } diff --git a/ydb/library/yql/tests/sql/dq_file/part4/canondata/result.json b/ydb/library/yql/tests/sql/dq_file/part4/canondata/result.json index ffad629cfa..c3ac485c08 100644 --- a/ydb/library/yql/tests/sql/dq_file/part4/canondata/result.json +++ b/ydb/library/yql/tests/sql/dq_file/part4/canondata/result.json @@ -1605,6 +1605,28 @@ } ], "test.test[expr-list_from_range_opt-default.txt-Results]": [], + "test.test[expr-list_to_from_tuple-default.txt-Analyze]": [ + { + "checksum": "b4dd508a329723c74293d80f0278c705", + "size": 505, + "uri": "https://{canondata_backend}/1814674/8156a7ce6ad6eceb82586ac4874de57d87023039/resource.tar.gz#test.test_expr-list_to_from_tuple-default.txt-Analyze_/plan.txt" + } + ], + "test.test[expr-list_to_from_tuple-default.txt-Debug]": [ + { + "checksum": "a91b3f2ddb772f271fd781c18455db2e", + "size": 1084, + "uri": "https://{canondata_backend}/1814674/8156a7ce6ad6eceb82586ac4874de57d87023039/resource.tar.gz#test.test_expr-list_to_from_tuple-default.txt-Debug_/opt.yql_patched" + } + ], + "test.test[expr-list_to_from_tuple-default.txt-Plan]": [ + { + "checksum": "b4dd508a329723c74293d80f0278c705", + "size": 505, + "uri": "https://{canondata_backend}/1814674/8156a7ce6ad6eceb82586ac4874de57d87023039/resource.tar.gz#test.test_expr-list_to_from_tuple-default.txt-Plan_/plan.txt" + } + ], + "test.test[expr-list_to_from_tuple-default.txt-Results]": [], "test.test[expr-longint_builtins-default.txt-Analyze]": [ { "checksum": "b4dd508a329723c74293d80f0278c705", diff --git a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json index cafcecc751..161b564769 100644 --- a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json +++ b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json @@ -5347,6 +5347,13 @@ "uri": "https://{canondata_backend}/1936997/00f46808be87e2ae2d4ac3ac45675b659c5ace45/resource.tar.gz#test_sql2yql.test_expr-list_takeskipwhileinclusive_/sql.yql" } ], + "test_sql2yql.test[expr-list_to_from_tuple]": [ + { + "checksum": "b6e85e05feb47c4c14e1fa9954ce5c95", + "size": 3018, + "uri": "https://{canondata_backend}/1936273/66a638a4446d7760fa83194c4f6ab8e79a46abc6/resource.tar.gz#test_sql2yql.test_expr-list_to_from_tuple_/sql.yql" + } + ], "test_sql2yql.test[expr-list_uniq]": [ { "checksum": "338a9dbb192084a632be4c818c35e5de", @@ -22420,6 +22427,13 @@ "uri": "https://{canondata_backend}/1880306/64654158d6bfb1289c66c626a8162239289559d0/resource.tar.gz#test_sql_format.test_expr-list_takeskipwhileinclusive_/formatted.sql" } ], + "test_sql_format.test[expr-list_to_from_tuple]": [ + { + "checksum": "a96e9960eb98c3d4417630c94783cea1", + "size": 318, + "uri": "https://{canondata_backend}/1936273/66a638a4446d7760fa83194c4f6ab8e79a46abc6/resource.tar.gz#test_sql_format.test_expr-list_to_from_tuple_/formatted.sql" + } + ], "test_sql_format.test[expr-list_uniq]": [ { "checksum": "5c0e33f6414470dbe607fc1cb11bba4a", diff --git a/ydb/library/yql/tests/sql/suites/expr/list_to_from_tuple.sql b/ydb/library/yql/tests/sql/suites/expr/list_to_from_tuple.sql new file mode 100644 index 0000000000..4f80b8976e --- /dev/null +++ b/ydb/library/yql/tests/sql/suites/expr/list_to_from_tuple.sql @@ -0,0 +1,11 @@ +select + ListFromTuple(null), + ListFromTuple(()), + ListFromTuple((1,2)), + ListFromTuple(just((3,4))), + ListFromTuple(Nothing(Tuple<Int32,Int32>?)), + ListToTuple(null,10), + ListToTuple([],0), + ListToTuple(ListCreate(Int32),0), + ListToTuple([1,2],2), + ListToTuple(just([3,4]),2); diff --git a/ydb/library/yql/tests/sql/yt_native_file/part4/canondata/result.json b/ydb/library/yql/tests/sql/yt_native_file/part4/canondata/result.json index 579203812d..685d21a1f9 100644 --- a/ydb/library/yql/tests/sql/yt_native_file/part4/canondata/result.json +++ b/ydb/library/yql/tests/sql/yt_native_file/part4/canondata/result.json @@ -1536,6 +1536,27 @@ "uri": "https://{canondata_backend}/1599023/401beb8b5eecc3a5fa746a4e9edc1175fdf7326f/resource.tar.gz#test.test_expr-list_from_range_opt-default.txt-Results_/results.txt" } ], + "test.test[expr-list_to_from_tuple-default.txt-Debug]": [ + { + "checksum": "6d90d912c1af13e53aec4013f17cc329", + "size": 1013, + "uri": "https://{canondata_backend}/1942525/5a2542f1fecc574bc61de9c75af61860fe531746/resource.tar.gz#test.test_expr-list_to_from_tuple-default.txt-Debug_/opt.yql" + } + ], + "test.test[expr-list_to_from_tuple-default.txt-Plan]": [ + { + "checksum": "b4dd508a329723c74293d80f0278c705", + "size": 505, + "uri": "https://{canondata_backend}/1942525/5a2542f1fecc574bc61de9c75af61860fe531746/resource.tar.gz#test.test_expr-list_to_from_tuple-default.txt-Plan_/plan.txt" + } + ], + "test.test[expr-list_to_from_tuple-default.txt-Results]": [ + { + "checksum": "e9c21674215af8aa0f13da3ae6068031", + "size": 5347, + "uri": "https://{canondata_backend}/1942525/5a2542f1fecc574bc61de9c75af61860fe531746/resource.tar.gz#test.test_expr-list_to_from_tuple-default.txt-Results_/results.txt" + } + ], "test.test[expr-longint_builtins-default.txt-Debug]": [ { "checksum": "218bfaa432db3a6726a4c6f033b9646d", |